richardtallent
richardtallent

Reputation: 35384

How can I get ASP.NET Core WebAPI method to bind to a model's boolean field?

I have a form that I'm posting to my WebAPI endpoint using JQuery:

<form>
  Email: <input type="email" name="email" /><br>
  Name: <input type="text" name="name" /><br>
  <input type="checkbox" name="agree" /> I wish to subscribe
</form>

...

function Subscribe() {
    $.ajax({
        url: "api/Subscription/subscribe",
        method: "POST",
        data: $("#SubscriptionForm").serialize()
    })
    .done(function() { alert("yay!"; })
    .fail(function() { alert(":("); });
}

This is, as expected, submitting the form in application/x-www-form-urlencoded form (e.g., [email protected]&name=Joe&agree=on). On the receiving end, my API method looks something like this:

[HttpPost("subscribe", Name = "Subscribe")]
public IActionResult Subscribe(Subscription subscription) {
    if(!ModelState.IsValid) {
        return BadRequest();
    }
    SubscriptionRepository.Create(subscription);
    return Ok();
}

Subscription is a POCO with some string and bool types corresponding to the form fields being submitted, e.g.:

public class Subscription {
   string Email { get; set; }
   string Name { get; set; }
   bool Agree { get; set; }
}

The Problem

As long as none of the checkboxes on the form are checked, the WebAPI method is able to bind the other form fields to the model successfully. But when at least one checkbox is selected, ModelState.IsValid returns false.

I suspect WebAPI is somehow incapable of converting the on value passed for a selected checkbox to a bool. This seems like a pretty basic, universal need, so am I missing something simple?

Upvotes: 2

Views: 1731

Answers (2)

Shyju
Shyju

Reputation: 218852

If the checkbox has a value attribute, it will be posted when the form is submitted (and check box is selected). If the checkbox was not selected and you try to submit the form, that item will not be submitted, so your boolean property will get the default value, false

If the checkbox does not have a value attribute, then when you select the checkbox and submit the form, the value "on" will be send ( that is what happening to you), If check box is not selected, nothing will be send for that element.

So simply add value="true" to your html which render the checkbox.

<form id="SubscriptionForm">
    Email: <input type="email" name="email" /><br>
    Name: <input type="text" name="name" /><br>
    <input type="checkbox" value="true" name="agree" /> I wish to subscribe
    <input id="submit" type="submit" />
</form>

Also you need to make sure that your properties are public ,otherwise model binder will not be able to set the values of those!

public class Subscription 
{
   public string Email { get; set; }
   public  string Name { get; set; }
   public  bool Agree { get; set; }
}

Upvotes: 1

Mustapha Larhrouch
Mustapha Larhrouch

Reputation: 3393

Try to catching the error using :

if (!ModelState.IsValid)
{
    var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));

    // Breakpoint, examine the list with Exceptions.
}

Upvotes: 0

Related Questions