liveBook · Manning

Validation

As explained in Pro ASP.NET Core 7, Tenth Edition

Validation is the process of checking data against rules to determine whether it is acceptable for processing.

Validation checks whether request data meets an application’s requirements before that data is used or stored. A missing value, an unusable price, or an invalid relationship can cause immediate errors or quietly leave bad data in a database. Rejecting the data is only half the job: the user also needs enough feedback to correct it. section 29.0 section 29.2

For an ASP.NET Core controller that accepts a form:

  • Put rules on model properties using attributes from System.ComponentModel.DataAnnotations. [Required] demands a value; [EmailAddress] checks an email address; [Range] sets numeric limits. Rules on a model can be reused by forms that bind to it. section 3.2.9 section 19.5.4
  • Let model binding populate the object and check ModelState.IsValid in the receiving action. Process valid data; return the form when validation fails. ModelState retains error details for the response. section 3.2.9 section 29.3
  • Show the errors. A form can use asp-validation-summary="All"; validation tag helpers can also mark invalid inputs with input-validation-error for CSS styling. Returning the same view preserves the validation context. section 3.2.9 section 29.3

An unanswered RSVP is not a “no”

An attendance choice uses bool? rather than bool. If the visitor makes no selection, model binding leaves it null and [Required] reports an error. A non-nullable bool could only be true or false, obscuring whether a choice was made. The POST action adds a valid response and shows a thank-you view; otherwise, it redisplays the form. section 3.2.9

Listing 3.17 Applying validation in the GuestResponse.cs file in the Models folder
using System.ComponentModel.DataAnnotations;

namespace PartyInvites.Models {

    public class GuestResponse {
 
        [Required(ErrorMessage = "Please enter your name")]
        public string? Name { get; set; }
 
        [Required(ErrorMessage = "Please enter your email address")]
        [EmailAddress]
        public string? Email { get; set; }
 
        [Required(ErrorMessage = "Please enter your phone number")]
        public string? Phone { get; set; }
 
        [Required(ErrorMessage = "Please specify whether you'll attend")]
        public bool? WillAttend { get; set; }
    }
}

See the model properties, their validation attributes, and the nullable attendance choice together. section 3.2.9

Listing 3.18 Checking for errors in the HomeController.cs file in the Controllers folder
using Microsoft.AspNetCore.Mvc;
using PartyInvites.Models;

namespace PartyInvites.Controllers {
    public class HomeController : Controller {
 
        public IActionResult Index() {
            return View();
        }
 
        [HttpGet]
        public ViewResult RsvpForm() {
            return View();
        }
 
        [HttpPost]
        public ViewResult RsvpForm(GuestResponse guestResponse) {
            if (ModelState.IsValid) {
                Repository.AddResponse(guestResponse);
                return View("Thanks", guestResponse);
            } else {
                return View();
            }
        }
 
        public ViewResult ListResponses() {
            return View(Repository.Responses
                .Where(r => r.WillAttend == true));
        }
    }
}

Follow the POST action’s ModelState.IsValid branch from accepted response to error redisplay. section 3.2.9

A REST endpoint needs a different error response. A product POST checks ModelState before saving: valid data produces Ok; invalid data produces BadRequest(ModelState) and HTTP 400. [Range] is useful for numeric properties that would otherwise default to zero when the request omits them. Do not assume every client can interpret the error body; there is no standard error description format here. section 19.5.4

Validation also belongs in database-backed create forms: bind the submitted object, check it, and save only acceptable data. If the editor view expects a different view-model type, rebuild that view model with the submitted data before redisplaying it. Basic checks during model binding can be supplemented with explicit custom validation; client-side and remote validation offer feedback before or alongside a server submission. section 31.2.3 section 29.8

How Pro ASP.NET Core 7, Tenth Edition covers it

How deep it goes
Works through attribute rules, ModelState branching, error display, and API responses; identifies custom and client-side validation without detailing their implementations.
Examples
Uses an RSVP form, a product API POST, and a database-backed product create form.
What it assumes
Assumes familiarity with ASP.NET Core actions, models, and forms; introduces validation as the check following model binding.
What you can do after
Build it from scratch with validation attributes, ModelState checks, form feedback, and a bad-request response for invalid API input.
How it connects
Connects model binding, data annotations, controller actions, Razor views, tag helpers, RESTful APIs, and Entity Framework Core.

Also explained in

Compare how 30 books explain validation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Pro ASP.NET Core 7, Tenth Edition. The section links point to the parts of the book it draws on.