Search code examples
c#asp.net-core-mvc.net-6.0modelstate

Populate View Model / ModelState.IsValid


I can't quite wrap my head around the model validation. Let's assume the following ViewModel:

public class UserEditViewModel
{
    public List<Role> AvailableRoles { get; set; }
    public string? SelectedRole { get; set; }   
}

The goal is to let the user select from a list of roles (think of a dropdown).

In the HttpGet I populate the list of available roles form a database like this:

UserEditViewModel uevm = new UserEditViewModel();
uevm.AvailableRoles = _db.Roles.ToList();

When I get the UserEditViewModel back from the HttpPost event, it will have an invalid model state:

if (ModelState.IsValid) { ...}

The validation will state that while the SelectedRole is valid, the list of available roles is NOT valid.

Now I can think of multiple solutions to this problem but am unsure on how to proceed:

  • I could create a custom constructor for the UserEditViewModel which populates the AvailableRoles list from a database. But this means that I will need to pass a reference to the database context into the UserEditViewModel
  • I could simply ignore the ModelState because I know it is invalid? What would I lose in this case?

I had some hope hat the Bind property would maybe help like this:

public ActionResult EditUser([Bind(include:"SelectedRole")] UserEditViewModel editViewModel, string id)

but it appears that ModelState is still invalid even if I specify I only want the SelectedRole.

This leads me to the ultimate question: What is the correct way to approach this issue?


Solution

  • Try to apply [ValidateNever] attribute to remove validate an unused property on the server side:

    public class UserEditViewModel
    {
        [ValidateNever]
        public List<Role> AvailableRoles { get; set; }
        public string? SelectedRole { get; set; }   
    }
    

    From the documentation:

    Indicates that a property or parameter should be excluded from validation. When applied to a property, the validation system excludes that property. When applied to a parameter, the validation system excludes that parameter. When applied to a type, the validation system excludes all properties within that type.

    But if it's necessary to avoid validation only when returning model data from a specific view use ModelState.Remove("AvailableRoles"); before if (ModelState.IsValid) {...}.