liveBook · Manning

Validation

As explained in ASP.NET Core in Action, 3e

Validation is the application framework process that checks model data against rules to determine whether it is acceptable.

Validation checks whether data meets the rules your application expects before you use it. Treat request values as untrusted: even an ordinary mistake, such as a missing name or a negative quantity, can cause trouble. Check values on the server before they reach business logic or infrastructure; browser checks can give faster feedback, but users can bypass them. section 7.10.1 section 16.3.1

A binding model can declare common rules with DataAnnotations:

  • [Required] distinguishes required values from optional ones; [EmailAddress] checks email format. section 16.3.1
  • [StringLength] and [Range] constrain length and numeric values. Other rules can enforce business requirements, such as preventing a currency from being converted to itself. section 16.3.1 section 32.3

Model binding makes request values available to a handler; validation then checks those values. In Razor Pages, validation runs automatically after binding and before the page handler. The handler still runs when validation fails, so check ModelState.IsValid before saving or otherwise using the input. On failure, return Page() to show the submitted values and errors; on success, continue with the intended action. section 16.3.1 section 16.3.2

Listing 16.7 Checking model state to view the validation result
public class CheckoutModel : PageModel                              #1
{
    [BindProperty]                                                  #2
    public UserBindingModel Input { get; set; }                     #2
 
    public IActionResult OnPost()                                   #3
    {
        if (!ModelState.IsValid)                                    #4
        {
            return Page();                                          #5
        }
 
        /* Save to the database, update user, return success */     #6
 
        return RedirectToPage("Success");
    }
}

The checkout handler returns Page() when ModelState is invalid, leaving the save operation and success redirect for valid input. section 16.3.2

Minimal APIs take a different route: they have no dedicated built-in validation API. Add validation through an endpoint filter, preferably early enough to stop invalid input before the handler uses it. MinimalApis.Extensions supplies WithParameterValidation(), a filter that checks DataAnnotations on a bound model. Invalid input produces a 400 Bad Request Problem Details response instead of running the endpoint handler. To apply its attributes to a simple route value, put the value in a type and bind it with [AsParameters]. section 7.10.1 section 7.10.3

Listing 7.12 Adding validation to minimal APIs using MinimalApis.Extensions
using System.ComponentModel.DataAnnotations;
 
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
WebApplication app = builder.Build();
 
app.MapPost("/users", (UserModel user) => user.ToString())
.WithParameterValidation();    #1
 
app.Run();
 
public record UserModel                #2
{
    [Required]
    [StringLength(100)]
    [Display(Name = "Your name")]
    public string Name { get; set; }
 
    [Required]
    [EmailAddress]
    public string Email { get; set; }
}
#1 Adds the validation filter to the endpoint
#2 The UserModel defines its validation requirements using DataAnnotations attributes.

The /users endpoint attaches WithParameterValidation() to a model with required, length, and email rules. section 7.10.3

DataAnnotations are a starting point, not the only option. A custom ValidationAttribute can check an allowed currency code, though adding client-side feedback takes separate work. FluentValidation instead keeps rules in validator classes, making multi-property rules and dependency injection easier to express. Choose the approach that fits the rules you need while keeping server-side checks in place. section 32.4 section 32.4.1 section 32.3

How ASP.NET Core in Action, 3e covers it

How deep it goes
Works through attributes, minimal API filters, and Razor Pages failure handling, then compares custom attributes with FluentValidation.
Examples
Uses a user-details form, a minimal API user endpoint, and currency-conversion rules to demonstrate valid and invalid input.
What it assumes
Assumes familiarity with C# or a similar language while introducing validation alongside model binding and web application examples.
What you can do after
Apply it via DataAnnotations and a minimal API filter, or check ModelState.IsValid in a Razor Pages handler.
How it connects
Links validation to model binding, DataAnnotations, endpoint filters, ModelState, server-side validation, and FluentValidation.

Also explained in

Compare how 30 books explain validation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of ASP.NET Core in Action, 3e. The section links point to the parts of the book it draws on.