How to automate model validation in ASP.Net Core

Take advantage of automatic model state validation in ASP.Net Core to avoid tedious manual coding for HTML form validation

How to automate model validation in ASP.Net Core
Thinkstock

When we create applications that accept data from users, we must validate that data before storing it in a database. The .Net Framework not only provides validation attributes to simplify checks for required input, data types, value ranges, and patterns (e.g. email addresses and credit card numbers), but ASP.Net Core can check for validation errors in submitted HTML form values automatically. 

A model state in ASP.Net Core is a collection of name-value pairs, along with validation information, that is sent to the server during a POST request. Any error messages included in the validation information are the model validation errors. The ApiController attribute introduced in ASP.Net Core 2.1 handles model state validation automatically. If the model state is invalid, it returns the appropriate error. 

This article presents a discussion of how we can work with this new feature in ASP.Net Core.

Create an ASP.Net Core application in Visual Studio

In this section we will create the ASP.Net Core application we will use to learn how we can work with the ApiController attribute. Follow the steps outlined below to create a new ASP.Net Core project in Visual Studio 2017.

  1. Launch the Visual Studio 2017 IDE.
  2. Click File > New > Project.
  3. Select the “ASP.Net Core Web Application” project template.
  4. Specify the name and location for your project.
  5. Click OK.
  6. In the “New ASP.Net Core Web Application” dialog window, select .Net Core.
  7. Select ASP.Net Core 2.1 as the project’s version.
  8. Select “Web API” as the project template.
  9. Uncheck the “Enable Docker Support” and “Configure for HTTPS” check boxes as we will not need these features here.
  10. Ensure that the message “No Authentication” is displayed; we won’t be needing authentication either. 
  11. Click OK. 

Before we leverage the ApiController attribute for automatic model state validation in ASP.Net Core 2.1, let’s examine how model state validation could be automated in ASP.Net Core 2.0.

Use automatic model state validation in ASP.Net Core 2.0

To automate model state validation in ASP.Net Core 2.0, we can take advantage of a custom action filter as shown in the code snippet below. Action filters are executed before model binding and before and after an action is executed. To create a custom action filter, you need to extend the ActionFilterAttribute class. It should be noted that this class is an implementation of the IActionFilter, IAsyncActionFilter, IResultFilter, IAsyncResultFilter, and the IOrderedFilter interfaces.

public class AutomaticModelStateValidatorAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
        {
            if (!actionExecutingContext.ModelState.IsValid)
            {
                actionExecutingContext.Result = new BadRequestObjectResult(actionExecutingContext.ModelState);
            }
        }
    }

Next, you can then write the necessary code to add the custom action filter in the pipeline in the ConfigureServices method of the Startup.cs file as shown below. The AutomaticModelStateValidatorAttribute is the name of the custom action filter class we implemented earlier.

public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options =>
            {
                options.Filters.Add(typeof(AutomaticModelStateValidatorAttribute));
            });
        }

And that’s all you have to do. But with ASP.Net Core 2.1, the job is even simpler. 

Use automatic model state validation in ASP.Net Core 2.1

In ASP.Net Core 2.1, the ApiController attribute will trigger automatic model validation without your having to write any custom code. The following code snippet shows the default ValuesController in ASP.Net Core 2.1 with the ApiController attribute applied when the project was created in Visual Studio.

[Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
            //The controller methods have been removed for clarity
    }

Next, we need a model to validate. Create a model class named Author as illustrated in the code snippet below. Note the usage of the [Required] and [StringLength] validation attributes. To use these attributes, you should include the System.ComponentModel.DataAnnotations namespace.

using System.ComponentModel.DataAnnotations;
public class Author
    {
        [Required]
        [StringLength(4)]
        public string Code { get; set; }
        [Required]
        [StringLength(50)]
        public string FirstName { get; set; }
        [Required]
        [StringLength(50)]
        public string LastName { get; set; }
    }

We will now examine how we can use this model class in our controller method and apply model validation.

Create a new controller named AuthorController. At first glance, the AuthorController will look like this:

 [Route("api/[controller]")]
    [ApiController]
    public class AuthorController : ControllerBase
    {
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }
        [HttpGet("{id}", Name = "Get")]
        public string Get(int id)
        {
            return "value";
        }
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }

Now, replace the default Post method with the one given below.

      [HttpPost]
        public IActionResult Post([FromBody]Author author)
        {
            if (ModelState.IsValid)
            {
                return Ok();
            }
            else
            {
                return BadRequest();
            }
        }

And that’s it! You can test how model validation works by making a POST call to the AuthorController. I will leave it to you to implement that piece.

Disable automatic model state validation in ASP.Net Core 2.1

Note that you can disable automatic model validation in ASP.Net Core 2.1. To do this, you need to set the SuppressModelStateInvalidFilter property of the ApiBehaviorOptions class to true in the ConfigureServices method, as shown below.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ApiBehaviorOptions>(options =>
    {
        options.SuppressModelStateInvalidFilter = true;
    });
}

Automatic model state validation saves work. When model validation is applied globally in the ConfigureServices method, you avoid having to write repetitive code in your action methods. All you need to do in your action methods is check if the model state is invalid and return error messages appropriately.

if (!ModelState.IsValid)
{
   // Write code to return bad request or errors or redirect elsewhere
}

An application should always validate data before it is stored in the database. While verifying the data, an application should check if the data is secure and conforms to your pre-defined rules. This process is also known as model validation. Although ASP.Net Core 2.1 enables you to automate model validation, you might sometimes want to disable automatic model state validation and validate your models programmatically, i.e., only when it is needed.

Copyright © 2018 IDG Communications, Inc.