0

I'm using a checkbox to handle allow Ordering function, which generates HTML code below:

@using (Html.BeginForm("EditFarm", "CustomerManagement", FormMethod.Post))
{
  @Html.AntiForgeryToken()
  @Html.ValidationSummary(true)
  @Html.HiddenFor(model => model.AllowOrder)

 <div>
   <label for="allowOrder">Allow Ordering</label>
   <br />
   <input type="checkbox" id="allowOrder" name="AllowOrder" value="true" @(Model.AllowOrder ? "checked" : "") />
 </div>
....
}

The problem is checkbox AllowerOrder always pass true value to Controller even when it's unchecked

This is code in Controller:

public ActionResult EditFarm([Bind(Include = "Id, ERPCustomerCode, ERPId, CategoryId, Size, Large, OtherId, AllowOrder")] NewFarm farm)
        {
           ...
        }

Tried the debug, received model always have AllowerOrder = true. enter image description here

Is there any issue in my code? Any help would be appreciated! Thanks!

10
  • On top of Yauhen's comment, your checkbox doesn't seem bound to AllowOrder. This one is more likely bound to it: @Html.HiddenFor(model => model.AllowOrder) Commented Mar 19, 2019 at 7:43
  • 1
    You should use @Html.CheckboxFor. Check here Commented Mar 19, 2019 at 7:45
  • Most likely @Html.HiddenFor(model => model.AllowOrder) overrides the checkbox value because it generates <input type="hidden" name="AllowOrder" />. Note that both elements have same name attribute. Commented Mar 19, 2019 at 7:46
  • 1
    I recommend using @Html.CheckBoxFor, what thing doesn't work? Is that related to checked attribute? I think just putting name attribute with input element is not enough to bind checkbox value for viewmodel property. Commented Mar 19, 2019 at 7:56
  • 1
    Agree with @TetsuyaYamamoto, a. Delete @Html.HiddenFor(model => model.AllowOrder) b. Use @Html.CheckBoxFor instead of <input type="checkbox" id="allowOrder" name="AllowOrder" value="true" @(Model.AllowOrder ? "checked" : "") /> Commented Mar 19, 2019 at 7:58

1 Answer 1

1

The most possible cause is you're binding to AllowOrder property using HiddenFor helper before using <input type="checkbox" />, which will generate input elements in this order:

<input name="AllowOrder" type="hidden" ... />

<input type="checkbox" id="allowOrder" name="AllowOrder" value="true" ... />

Since there are 2 input elements with same name attribute value, only the first <input> element will bound to viewmodel property, which contains true value in your case. Instead of creating checkbox manually with <input> tag and hidden field separately, you should use @Html.CheckBoxFor() helper and toggle checked attribute using a helper function below or use ternary operator:

public object SetChecked(bool value)
{
    if (value)
    {
        return new { id = "allowOrder", @checked = "checked" };
    }
    else
    {
        return new { id = "allowOrder" };
    }
}

Checkbox

@* alternative 1 *@

@Html.CheckBoxFor(model => model.AllowOrder, @(SetChecked(Model.AllowOrder)))

@* alternative 2 *@

@Html.CheckBoxFor(model => model.AllowOrder, new { id = "allowOrder", @checked = @(Model.AllowOrder ? "checked" : "") })

Note: checked is a C# keyword, hence it needs to be escaped with @ to set it as HTML attribute of rendered <input type="checkbox" />.

Sign up to request clarification or add additional context in comments.

1 Comment

Note that the SetChecked function (as you wrote it) is only usable for one checkbox, as you set the id without a parameter. Hence I would rather use the second alternative, or add an id parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.