Почему ASP.NET MVC Html.CheckBox выводит два входа с одинаковым именем?

Почему в мире делает линию:

<%= Html.CheckBox("ForSale", Model.Product.ForSale)%> For Sale

результат в следующем HTML:

<input id="ForSale" name="ForSale" type="checkbox" value="true" />
<input name="ForSale" type="hidden" value="false" />
For Sale

Теперь, когда я проверяю флажок и доступRequest.Form["ForSale"]Я получаю нелепый ответ"true,false", Я должен разобрать это?

Это скрытое поле не отображается для других элементов управления HtmlHelper, так почему оно используется для CheckBox?

How do I turn this stupid "feature" off? Или сделалHtmlHelper просто перерасти свою полезность?

Update

Из ответа ниже кажется, что за этим стоит некоторая логика. Я подготовил небольшой метод расширения, поэтому мне не нужно об этом думать (спасибо @ eu-ge-ne):

    public static bool GetCheckBoxValue(this System.Web.HttpRequestBase req, 
                                        string name) {
        return Convert.ToBoolean(req.Form.GetValues(name).First());
    }
 Matthew Groves15 июл. 2009 г., 15:27
Ну, это не ответ на ваш вопрос, почему :) Я бы предложил использовать связующее для моделей (то есть, что сказал Брэд).
 Frank Krueger14 июл. 2009 г., 21:16
@mgroves возражают опубликовать ответ, чтобы сообщить мне, что я, вероятно, делаю неправильно?
 Brad Wilson15 июл. 2009 г., 14:52
Почему бы вам просто не указать логическое значение в сигнатуре метода действия и позволить связыванию модели выполнить эту работу за вас?
 Eric Petroelje14 июл. 2009 г., 21:08
+1 - я только что столкнулся с этим вопросом на днях. Похоже, они пытались быть полезными, но в итоге раздражали тех из нас, кто действительно знает, как должны работать флажки.
 Matthew Groves14 июл. 2009 г., 21:07
Если вы используете Request.Form, вы, вероятно, делаете это неправильно.

Ответы на вопрос(7)

Решение Вопроса

Это заставляет поле быть включенным, если оно не проверено. Если вы снимите флажок, он не будет отправлен как часть страницы - он будет отправлен только в том случае, если он проверен, а затем будет установлено значение true. Скрытое поле гарантирует, что false будет отправлено, если флажок снят, поскольку скрытое поле всегда отправляется.

 Frank Krueger14 июл. 2009 г., 21:08
Так я должен разобрать строку?
 07 нояб. 2013 г., 18:49
Чтобы развернуть: если ваша подпись метода действия похожа наpublic ActionResult b(bool b = false), то дополнительный генерируется<input/> не имеет значения. Если подпись вашего метода действияpublic ActionResult b(bool b = true) или жеpublic ActionResult b(bool b), затемb будет установленfalse если флажок включен, но не отмечен в определенной форме иb будет установленtrue или сгенерируйте ошибку, соответственно, в формах, где вы не включите флажок. этоHtml.CheckBox() поведение гарантирует, что & # x201C; unchecked & # x201D; всегда правильно отображается наfalse и что форма соответствует методу действия.
 15 июл. 2009 г., 15:44
Вы не должны анализировать строку, а также не использовать объект Request непосредственно в своем действии: просто используйте логическое значение в качестве одного из параметров метода действия, и все будет обработано за вас.

Now whenever I check the box and access Request.Form["ForSale"], I get the ridiculous answer of "true,false". Am I supposed to parse that?

Попробуй это:

var ForSale = Convert.ToBoolean(Request.Form.GetValues("ForSale").First());

UPDATED:

What if in the next MVC build it will return the value in the revers order "false, true"? ... – Mastermind

var ForSale = Request.Form.GetValues("ForSale")
    .Select(x => x.ToUpperInvariant()).Contains("TRUE");

// or

// FormatException can be thrown from Convert.ToBoolean()
var ForSale = Request.Form.GetValues("ForSale")
    .Select(x => Convert.ToBoolean(,x)).Contains(true);
 14 июл. 2009 г., 22:03
@Frank Krueger - надеюсь, не в MVC2
 14 июл. 2009 г., 21:16
Что, если в следующей сборке MVC он вернет значение в обратном порядке & quot; false, true & quot ;? Это работоспособное, но не надежное решение. Именно поэтому я отказался от встроенных помощников и сделал свой собственный.

пытаться

request.form["chkBoxes"].replace("false","").split(new char[] {','}, stringsplitoptions.removeemptyentries);

Я выбрал другой подход:

Не используйте вспомогательный метод Html.CheckBoxFor или Html.CheckBox для визуализации флажка, но визуализируйте его с использованием обычного HTML:

<input id="ShowOther" name="ShowOther" value="<%=Model.ShowOther %>" type="checkbox" <% if (Model.ShowOther)  { %>checked="checked"<% } %> />

И я добавил скрипт jQuery, который устанавливает значение, когдаcheckbox проверено / не проверено.

<script type="text/javascript">
    $(function() {
        $('#ShowOther').click(function() {
            var checked = $(this).attr('checked');
            if (checked != undefined)
                $(this).val(true);
            else
                $(this).val(false);
        });
    });
</script>

Насколько я мог проверить это, кажется, что правильныйvalue всегда отправляется в контроллер, и больше никаких проблем с"true,false".

Если флажок не отмечен, он не будет включен в отправку формы. Так что это "особенность" дает вам результат для каждого CheckBox. Те, которые не отмечены, будут просто "ложными".

Я реализовал свои собственные вспомогательные функции CheckBox, которые работают по-разному. Большую часть времени я не хочу просто true или false, а просто набор значений отмеченных флажков. Он отлично подходит для выбора определенных элементов по их идентификатору, для которого необходимо выполнить действие. Я не хочу, чтобы пункты, не отмеченные галочкой, даже в списке.

Вы можете взглянуть на исходный код для расширений HTML и использовать аналогичную структуру для создания собственных методов CheckBox.

http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectName=aspnet#288010

Я бы опубликовал свой, но я не использую стандартный класс HtmlHelper, так что это, вероятно, будет более запутанным. Я добавил параметр value в свои функции CheckBox, чтобы я мог использовать конкретное значение id вместо & quot; true & quot; или "ложь".

Вот как я это сделал в одном из моих приложений. Расстраивает, но, похоже, работает.

public virtual ActionResult Edit(int id, FormCollection values)
{
    SomeObject dbData = _repository.GetSomeObject(id);

    try
    {
        UpdateModel(dbData);
        if (values.GetValues("CheckBoxId").Contains("true")) 
            dbData.SomeBooleanProperty = true;
        else 
            dbData.SomeBooleanProperty = false;

        _repository.Save();

        Session["Success"] = "Successfully edited the part.";
        return RedirectToAction("Index");
    }
    catch
    {
        // Handle validation errors here
        return View(new SomeObjectFormViewModel(dbData));
    }
}

Надеюсь это поможет. Если у вас есть какие-либо дополнительные вопросы, просто оставьте комментарий, и я соответствующим образом обновлю свой ответ.

Я думаю, что самое чистое решение - это сделать:

(bool)formCollection["key"].ConvertTo(typeof(bool))

Ваш ответ на вопрос