We have seen how input parameters receive the data from incoming http requests. In this article, let’s see what is model validation and how to specify (or trigger it).
What is model validation ?
.NET Core Web API Controllers have actions to process the incoming requests. Every action defines how the incoming http requests would be mapped to input parameters. Technically, mapping incoming http request data to action’s input parameters is called as Model Binding.
During model binding, the data is also converted to appropriate target type. This conversion might result into errors if the type cannot be converted.
In addition, web APIs also support the concept of model validation. Once the model binding is done, optionally, inputs can also be validated. This process is called as Model Validation.
There are various type of validations which can be performed. e.g. let’s say, an action has two parameters – id and name. The integer input, id, is allowed to have any value greater than 0 but less than or equal to 10. Second parameter, name, should have length less than 50 characters.
What is model state ?
The model state represents (as the name suggests) state of the model. It represent all the errors that occurred during model binding and model validations.
Model binding errors are generally type conversion errors, while model validation errors are generally the validations specified on models to ensure that data adheres to certain business rules.
ModelState.IsValid is the property which can be used to check if there are errors. If this is true, means model is valid and there are not validation errors.
Next obvious question is how the model state property is populated ? Model state property is populated by model validation activity.
Who performs validation ?
Both model binding and model validation occurs before an action is executed.
For web apps (MVC or Razor pages app), it is responsibility of individual actions to check
ModelState.IsValid property and then react based on its value. Web apps, typically, may decide to show error messages or error pages to the end user.
For Web APIs, it works a bit different. The API controllers do not need to check for
ModelState.IsValid property. This property is automatically checked and if the model is found to be invalid, an automatically HTTP 400 response is returned to the caller.
Can we retrigger validation ?
In some cases, a controller might want to retrigger the validation from within an action.
For retriggering the validation, call TryValidateModel method, pass the object and its type as parameters. If this method returns true, it means the model is found to be valid.
How to specify validation rules ?
Validation rules can be specified using Attributes. .NET provides various in-built validation attributes, which can be used for specifying rules. These attributes can be specified on properties of the model, which needs to be validated.
Below is the list of common validation attributes:
- [ValidateNever] – to exclude a property from model validation
- [Required] – to ensure that a property is not null.
- [StringLength] – to specify min and max length of a string
- [Range] – to ensure that incoming value falls between specified range
- [RegularExpression] – to ensure that the incoming value matches a pattern specified by Regex
- [Phone] – to ensure that input has a valid phone number format
- [EmailAddress] – to ensure that incoming property is a valid
- [CreditCard] – to ensure that input conforms to valid credit card format
- [Url] – to ensure that the property is valid URL.
- [Compare] – to match two properties from same model
Many of these attributes take some parameters. Most of these attributes take
ErrorMessage as a parameter. This error message (or collection of messages) is returned to the caller if the model validation has failed. If the error message is not specified, then default error message is picked by the attribute.
In addition to this, there can be other inputs. For example,
RegularExpression attribute takes pattern as input.
StringLength attribute takes min and max lengths allowed.
Below example shows a controller and a model which has validation attributes placed on its properties.
Run and Verify
We can run the API project and it would show a swagger page. It can be used to test the API.
If all inputs (or some of them) are invalid, then API returns HTTP 400 and the response also contains the error messages.
If all valid inputs are provided, then the exact same data is returned by the API.
So, that was it. That was the introduction to how model validation works in .NET Core web APIs.
I hope you find this information useful. Let me know your thoughts.