9

I'm incorporating WebAPI into my development and am Posting all form submissions to a WebAPI controller. I've noticed that checkboxes are not getting bound to the model correctly. I have a form using:

@Html.CheckBoxFor(m => m.HasVideo)

It produces a checkbox and a hidden form element. When I check the checkbox (meaning a "true" value), the model binding in my WebAPI Post reflects a false for the HasVideo property. I moved the entire method over to a traditional mvc controller, and the binding works as expected.

Is there a workaround for this, or is there something that I'm missing?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Tom Schreck
  • 5,177
  • 12
  • 68
  • 122
  • See this post, the solution had to do with clearing out view data. Maybe this is this is the same issue. http://stackoverflow.com/questions/11993424/asp-net-mvc3-checkboxform-m-go-is-unchecked-even-though-my-model-go-is-t – CD Smith Aug 16 '12 at 23:00
  • 4
    The issue in the linked SO post was that the OP did not know about how html helpers for input controls bind. When using Html helpers for input controls they have an order, if a model is sent back to a view following an error the helpers will always render the original posted data instead of any data the model may contain. This is intentional to preserve the input on a failed submit. That is why clearing the model-state solved the problem. This issue however doesn't sound the same as the binding is fine in a normal controller but not in a WebAPI controller. – Nope Aug 16 '12 at 23:51
  • Is right value of your checkbox in Request.Form on server? – Kirill Bestemyanov Aug 17 '12 at 05:02
  • No, not for webapi. I see both true and false. I have a work around in place - use old fashion HTML radio buttons. I really think this is a bug in webapi. – Tom Schreck Aug 21 '12 at 18:17
  • @TomSchreck `` Then just add `bool paramName` to your action method signature. No need for radio buttons. Don't quote me on this, but I'm pretty sure that if it's checked, it will pass to your action as true. If it's not, it either passes back false or null. Hope this helps. – Mr Jones Aug 29 '12 at 18:56
  • i have this same problem. i get both true and false sent and model binder gives me false for the property. – eatfrog Sep 13 '12 at 07:50
  • try `@Html.CheckBoxFor(m => m.HasVideo, new { value = "true" })` to set the HTML value attribute. This will ensure that the value 'true' gets sent to the controller when the checkbox is checked, rather than the default "on" for most browsers. – Steve Lydford Sep 16 '12 at 12:38
  • I am not sure why your binding isn't working when getting saved to the model, but MVC will always create both the checkbox and the hidden input. Check [here](http://stackoverflow.com/questions/5462967/razor-viewengine-html-checkbox-method-creates-a-hidden-input-why) for a reason as to why. I had a similar problem, and found that none of my binding was working and I just assumed it was only the checkbox (because of that extra hidden element that was added). – Quickhorn Sep 26 '12 at 19:21
  • Why are you trying to post to WebApi? Are you expecting to return XML or JSON? If the expected result is HTML, you should be using a standard ActionResult in a Web controller. – viperguynaz Dec 09 '12 at 19:28

3 Answers3

7

dont use this html helper :

@Html.CheckBoxFor(m => m.HasVideo)

try this instead :

<input id="HasVideo" name="HasVideo" type="checkbox" value="true" @(((Model!=null) && Model.HasVideo) ? "checked=\"checked\"" : "" ) />
Chtioui Malek
  • 11,197
  • 1
  • 72
  • 69
  • I had similar issue and when I checked, it is bcos of the -- value="true" -- attribute, it is getting posted to the controller. If you remove the value attribute, it will show as false in the controller action always. – Venugopal M May 14 '15 at 08:04
1

I have seen this too. There isn't much on the web about this, and it should be more documented somewhere. The standard controllers will prefer true over false if it finds both, but the api controllers look like they just uses the last value found.

This page contains some information that might support this hypothesis: http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx

Sprintstar
  • 7,938
  • 5
  • 38
  • 51
0

Seen this issue before and its usually ViewData/ViewBag interference which is a nightmare to debug usually.

You can add a ViewBag.Clear/ViewData.Clear in the function which is giving you an issue.

Cheers, J

Jamie
  • 876
  • 1
  • 10
  • 28