Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: Model binding half an object

I have a form to add a new user with a few checkboxes for user roles. I have a model in my action called User which has the following properties:

public string Username { get; set; }
public string Password { get; set; }
public IEnumerable<UserRole> Roles { get; set; }

Inside the UserRole class I have two properties:

public int Id { get; set; }
public string Name { get; set; }

In my form I can successfully bind to Username and Password no problem by giving the input names 'Username' and 'Password'. When the page initially loads the user role details are loaded and so all I need to pass back in is the Id because this is what the service needs to associate a user with a user role.

I thought I could do this the simple way by giving each checkbox the value of the role Id and passing that in to Roles therefore partially completing the roles class and leaving the Name field of the role object blank. An example checkbox looks like this:

<input type="checkbox" id="addUserAdministrator" name="Roles.Id" value="@Model.Roles.Where(role => role.Name == "Administrator").Select(role => role.Id).First()" class="css-checkbox"/>

However this never populates the Roles collection and it is always null. Is there a way of doing this or will I need to do the long winded way of passing in a list on ints and creating the model in the action?

EDIT:

My action looks like this:

public RedirectToRouteResult Add(User user)
like image 645
Serberuss Avatar asked Jul 05 '26 20:07

Serberuss


1 Answers

Either you can bind a collection of primitive type - int in your case

 public IList<Int> Roles { get; set; } //role id's here

using

<input type="checkbox" id="addUserAdministrator" name="Roles"

or if you want Roles collection you should explicitly specify an indexing to your collections. Read this article. It's better to use non-sequential indexing (e.g. using Guid.NewGuid()) in case of gaps between selected items in list on the form.

<input type="hidden" name="Roles.Index" value="@(GuidIndexForThisRow)" />
<input type="checkbox" name="Roles[@(GuidIndexForThisRow)].Id" value="1" />
like image 127
lavrik Avatar answered Jul 07 '26 10:07

lavrik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!