Search code examples
asp.net-core

ASP.NET Core ModelState ignore ScaffoldColumn


I have a view model like this.

public class ModelTest
{
    public ModelTest()
    {
        Name = "Jim";
    }

    [Required]
    public string Name { get; set; }

    [ScaffoldColumn(false)]
    public string IgnoreMe { get; set; }
}

and an Action

    public IActionResult TestModel(ModelTest model)
    {
        var valid = ModelState.IsValid;

        return Json(ModelState);
    }

Previously in ASP.NET MVC 5 this would be valid as the DataAnnotationsModelValidatorProvider ignored ScaffoldColumns when performing validation, so the ModelState.IsValid would be true. But in ASP.NET MVC Core 8 it is false and the ModelState is

{
    "IgnoreMe": {
        "RawValue": null,
        "AttemptedValue": null,
        "Errors": [
            {
                "Exception": null,
                "ErrorMessage": "The IgnoreMe field is required."
            }
        ],
        "ValidationState": 1,
        "IsContainerNode": false,
        "Children": null
    }
}

Is there any way to change this behaviour and ignore ScaffoldColumn's?


Solution

  • Previously in ASP.NET MVC 5 this would be valid as the DataAnnotationsModelValidatorProvider ignored ScaffoldColumns when performing validation, so the ModelState.IsValid would be true. But in ASP.NET MVC Core 8 it is false and the ModelState is false

    The reason why the validation return false in asp.net core is not related with the [ScaffoldColumn(false)] attritbute, it is related with the new feature Nullable reference types in C#, in the asp.net core it will check string property to not allow null by default.

    Details, you could refer to this article.

    To avoid the string validation checking ,you could modify the model like below:

    public class ModelTest
    {
        public ModelTest()
        {
            Name = "Jim";
        }
    
        [Required]
        public string Name { get; set; }
    
        [ScaffoldColumn(false)]
        public string? IgnoreMe { get; set; }
    }
    

    Besides, this s behavior can be disabled by configuring SuppressImplicitRequiredAttributeForNonNullableReferenceTypes in Program.cs:

    builder.Services.AddControllers(
        options => options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true)