Mister Epic
Mister Epic

Reputation: 16733

ModelState is marked invalid for an empty non-required field

A bit of a mystery. I have a viewmodel with a Year property:

public class TradeSpendingSalesViewModel
{       
    public string ProductCode { get; set; }
    public IEnumerable<SelectListItem> AllowTypeSelect { get; set; }
    public string AllowType { get; set; }
    public IEnumerable<SelectListItem> YearsSelect { get; set; }
    public int Year { get; set; }
}

If I post an empty viewmodel to my controller:

[HttpPost]
public ActionResult Index(TradeSpendingSalesViewModel vm)
{
    var allErrors = ModelState.Values.SelectMany(v => v.Errors);
    foreach (var e in allErrors)
    {
        Response.Write(e.ErrorMessage);
    }
}

Then I get a single error with a message of: "The Year field is required."

Since I haven't annotated the viewmodel Year field with the Required attribute, I'm unclear why this error is being generated.

Any ideas?

Upvotes: 14

Views: 6782

Answers (3)

Boyesz
Boyesz

Reputation: 113

It's still can be an issue in .NET Core projects. I found a solution here:

https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-8.0#non-nullable-reference-types-and-required-attribute

.NET will mark your parameter as invalid if it's not a nullable type as required. You can set the SuppressImplicitRequiredAttributeForNonNullableReferenceTypes property to true in your MvcOptions. Example in Program.cs:

services.AddControllers(option =>
{
    option.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
});

When you set this up. It will only check only the required attribute. Or you can use the "?" mark to make your properties nullable, and that'll work too.

Upvotes: 2

Dima
Dima

Reputation: 6741

ValueTypes by default are implicitly marked as Required in mvc. This was done for purpose, actually, because they by definition are non-nullable.

I would suggest you to set Year as int?, otherwise, if it's not correct in your case, you may change to false

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes

in Global.asax.cs.

Upvotes: 18

Anthony Shaw
Anthony Shaw

Reputation: 8166

My first guess would be that it is throwing an exception that you're not setting year and it's null? if you made year a Nullable<int> does it not throw the required message?

I still wouldn't expect it to be required, it's a shot in the dark

Upvotes: 15

Related Questions