Home > Enterprise >  .net core MVC tries validate IEnumerable options for dropdown, but Required attr is only "expre
.net core MVC tries validate IEnumerable options for dropdown, but Required attr is only "expre

Time:11-10


I have an issue with model validation in webapp (.NET core MVC) - in form there are few dropdown lists, these DDLs have as expression required non-nullable int parameter and SelectListItem option list. I am getting message the SelectListItem option lists are required (the int parameter pass as valid). What is wrong or what I missed?

Model (MyModel f.e.):

    [Required]
    [Display(Name = nameof(MyResources.Day), ResourceType = typeof(MyResources))]
    public int Day { get; set; }
    
    public IEnumerable<SelectListItem> Days { get; set; }

Controller, GET method

    [HttpGet]
    public IActionResult Index() {
        var model = MyModel();
        FillModelOptions(model);
        return View(model);
    }

    [HttpPost]
    public IActionResult Index(MyModel model) {
        if (ModelState.IsValid) {
            *save form, go somewhere*
        }
        FillModelOptions(model);
        return View(model);
    }

    private void FillModelOptions(MyModel model) {
        var days = new List<SelectListItem>();
        for (var i = 1; i < 32; i  ) {
            days.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString() });
        }
        
        model.Days = days.AsEnumerable();
    }

In view I have @Html.ValidationSummary(false, "") and this returns me hidden error: The Days field is required. (but the Days is IEnumerable, and Day is not empty)

View:

    @using (Html.BeginForm("Index", "MyController", FormMethod.Post) {
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(false, "") @*after post getting The Days field is required*@
        
        <div >
            @Html.DropDownListFor(model => model.Day, Model.Days, "Select...", new {@, @aria_label="Select..."})
            @Html.LabelFor(model => model.Day)
            @Html.ValidationMessageFor(model => model.Day)
        </div>
    }

CodePudding user response:

You write the property like this in MyModel :

public IEnumerable<SelectListItem> Days { get; set; }

enter image description here

The Days property is non-nullable(Equivalent to hermit adding a [Required] property) by default, So if you don't bind any value to this property, ModelState.IsValid will return false.

If you don't want this, you can disable this by deleting the below line from the csproj file or setting it as disable. By default(.Net 6) value is enable.

<Nullable>enable</Nullable>

Or, you can just add ? to make it nullable:

public IEnumerable<SelectListItem>? Days { get; set; }

Or, make ModelState ignore this property:

if (ModelState.Remove("Days"))
{
      *save form, go somewhere*
}
  • Related