Why does ASP.NET MVC Html.CheckBox output two INPUTs with the same name?

后端 未结 7 804
不知归路
不知归路 2020-12-03 17:07

Why in the world does the line:

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

result in the following HTML:

<
相关标签:
7条回答
  • 2020-12-03 17:11

    If a CheckBox is not checked, then it will not be included in the form submission. So this "feature" gives you a result for every CheckBox. Those that are not checked will be simply "false".

    I have implemented my own CheckBox helper functions that work differently. Most of the time I don't want just true or false, but just a collection of the values of the checked boxes. It's great for selecting certain items by their id on which to perform an action. I don't want the unchecked items even in the list.

    You can take a look at the source code for the html extensions and use a similar structure to create your own CheckBox methods.

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

    I would post mine, but I'm not using the standard HtmlHelper class, so it would probably be more confusing. I did add a value parameter to my CheckBox functions so that I can use a specific id value instead of "true" or "false".

    0 讨论(0)
  • 2020-12-03 17:13

    It forces the field to be included if it's unchecked. If you uncheck a check box it doesn't get sent as part of the page - they are only sent if they're checked, and then there's a value of true. The hidden field ensures that false will be send if the check box is unchecked, as the hidden field is always sent.

    0 讨论(0)
  • 2020-12-03 17:24

    I took a different approach:

    Do not use the Html.CheckBoxFor or Html.CheckBox helper method to render a checkbox, but render it using normal html:

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

    And I've added a jQuery script which sets the value when the checkbox is checked/unchecked.

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

    As far as I could test this, it seems that the correct value is always sent to the Controller, and no more issues with "true,false".

    0 讨论(0)
  • 2020-12-03 17:28

    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?

    Try this:

    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);
    
    0 讨论(0)
  • 2020-12-03 17:32

    Here's how I've done it in one of my apps. Frustrating, but it seems to work.

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

    Hope this helps. If you've got any follow-up questions, just leave a comment and I'll update my answer accordingly.

    0 讨论(0)
  • 2020-12-03 17:32

    I think the cleanest solution is to do:

    (bool)formCollection["key"].ConvertTo(typeof(bool))
    
    0 讨论(0)
提交回复
热议问题