Подтвердить что ты не робот

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

Почему в мире есть строка:

<%= 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?

Как отключить эту тупую "функцию"? Или изменил ли ее HtmlHelper его полезность?

Обновление

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

    public static bool GetCheckBoxValue(this System.Web.HttpRequestBase req, 
                                        string name) {
        return Convert.ToBoolean(req.Form.GetValues(name).First());
    }
4b9b3361

Ответ 1

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

Ответ 2

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

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));
    }
}

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

Ответ 3

Я использовал другой подход:

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

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

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

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

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

Ответ 4

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

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

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

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

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

Ответ 5

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

Попробуйте следующее:

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

ОБНОВЛЕНО:

Что делать, если в следующей сборке MVC он вернет значение в порядке "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);

Ответ 6

попробуйте

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

Ответ 7

Думаю, самое чистое решение:

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