CodeOath
← All posts
.NET Core / Web API70 min total · 19 parts

Building REST APIs with ASP.NET Core: Routing, Middleware, and Dependency Injection

Contents — Part 7 of 19: Model Validation with Data Annotations
Part 7 of 19 · ~1 min

Model Validation with Data Annotations

public class CreateOrderRequest
{
    [Required]
    [StringLength(100, MinimumLength = 2)]
    public string CustomerName { get; set; } = "";

    [Range(1, 100)]
    public int Quantity { get; set; }

    [EmailAddress]
    public string? ContactEmail { get; set; }
}

Because of [ApiController], a POST with a missing CustomerName or Quantity: 0 never reaches your Create method's body at all — the framework returns a 400 with a structured error response describing exactly which field failed, automatically. Without [ApiController], the same validation still runs and populates ModelState, but you'd have to check it manually:

[HttpPost]
public IActionResult CreateManual(CreateOrderRequest request)
{
    if (!ModelState.IsValid) return BadRequest(ModelState); // needed only WITHOUT [ApiController]
    // ...
}

Data annotations cover common cases well but can't express validation that depends on multiple fields together (e.g. "end date must be after start date") without implementing IValidatableObject on the model, or moving to a dedicated validation library (FluentValidation is the common real-world choice) for anything beyond simple per-field rules.