October 8, 2020 08:45 by
Peter
Validating user input is a basic function in a web application. For production systems, developers usually spend a lot of time writing a lot of code to complete this function. If we use Fluent Validation to build the ASP.NET Core Web API, the task of input validation will be much easier than before. Fluent Validation is a very popular. NET library for building strong type validation rules.
Configuration project
Step 1: Download fluent validation
We can use nuget to download the latestFluentValidationlibrary
PM> Install-Package FluentValidation.AspNetCore
Step 2: Add the Fluent Validation service
We need to be in the ____________Startup.csAdd Fluent Validation Service to File
public void ConfigureServices(IServiceCollection services)
{
// mvc + validating
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddFluentValidation();
}
Adding Checker
FluentValidationA variety of built-in calibrators are provided. In the following examples, we can see two of them.
NotNull Checker
NotEmpty Checker
Step 1: Add a data model that needs to be validated
Now let’s add oneUserClass.
public class User
{
public string Gender { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string SIN { get; set; }
}
Step 2: add verifier class
UseFluentValidationTo create a validator class, the validator class needs to inherit from an abstract classAbstractValidator
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
//Add rules here
}
}
Step 3: Add validation rules
In this example, we need to verify that FirstName, LastName, SIN can’t be null, can’t be empty. We also need to verify that the SIN (Social Insurance Number) number is legitimate.
public static class Utilities
{
public static bool IsValidSIN(int sin)
{
if (sin < 0 || sin > 999999998) return false;
int checksum = 0;
for (int i = 4; i != 0; i--)
{
checksum += sin % 10;
sin /= 10;
int addend = 2 * (sin % 10);
if (addend >= 10) addend -= 9;
checksum += addend;
sin /= 10;
}
return (checksum + sin) % 10 == 0;
}
}
Here we areUserValidatorClass, add validation rules
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.FirstName)
.NotEmpty()
.WithMessage("FirstName is mandatory.");
RuleFor(x => x.LastName)
.NotEmpty()
.WithMessage("LastName is mandatory.");
RuleFor(x => x.SIN)
.NotEmpty()
.WithMessage("SIN is mandatory.")
.Must((o, list, context) =>
{
if (null != o.SIN)
{
context.MessageFormatter.AppendArgument("SIN", o.SIN);
return Utilities.IsValidSIN(int.Parse(o.SIN));
}
return true;
})
.WithMessage("SIN ({SIN}) is not valid.");
}
}
Step 4: Injecting authentication services
public void ConfigureServices(IServiceCollection services)
{
// Add validator
services.AddSingleton<IValidator<User>, UserValidator>();
// mvc + validating
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddFluentValidation();
}
Step 5:Startup.csManage your validation errors
In ASP.NET Core 2.1 and above, you can override the default behavior (ApiBehavior Options) managed by ModelState.
public void ConfigureServices(IServiceCollection services)
{
// Validators
services.AddSingleton<IValidator<User>, UserValidator>();
// mvc + validating
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddFluentValidation();
// override modelstate
services.Configure<ApiBehaviorOptions>(options =>
{
options.InvalidModelStateResponseFactory = (context) =>
{
var errors = context.ModelState
.Values
.SelectMany(x => x.Errors
.Select(p => p.ErrorMessage))
.ToList();
var result = new
{
Code = "00009",
Message = "Validation errors",
Errors = errors
};
return new BadRequestObjectResult(result);
};
});
}
When data model validation fails, the program executes this code.
In this example, I set up how to display errors to the client. In the returned result here, I just include an error code, error message and error object list.
Let’s take a look at the final results.
Using Verifier
Verifier is very easy to use here.
You just need to create an action and put the data model that needs to be validated into the action parameters.
Since the authentication service has been added to the configuration, when this action is requested,FluentValidationYour data model will be validated automatically!
Step 1: Create an action using the data model to be validated
[Route("api/[controller]")]
[ApiController]
public class DemoValidationController : ControllerBase
{
[HttpPost]
public IActionResult Post(User user)
{
return NoContent();
}
}