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





























