Почему ASP.NET MVC Html.CheckBox выводит два входа с одним и тем же именем? - PullRequest
30 голосов
/ 14 июля 2009

Почему в мире появляется строка:

<%= 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());
    }

Ответы [ 7 ]

38 голосов
/ 14 июля 2009

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

6 голосов
/ 15 сентября 2010

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

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

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

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

<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" .

3 голосов
/ 14 июля 2009

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

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

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

2 голосов
/ 14 июля 2009

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

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

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

ОБНОВЛЕНИЕ:

Что если в следующей сборке MVC он вернет значение в обратном порядке "false, true"? ... - вдохновитель

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);
2 голосов
/ 14 июля 2009

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

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

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

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

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

0 голосов
/ 14 ноября 2009

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

(bool)formCollection["key"].ConvertTo(typeof(bool))
0 голосов
/ 02 ноября 2009

попробуй

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...