Working of validation

How validation works

You might wonder how the validation UI was generated without any updates to the code in the controller or views.

The following code shows the two Create methods.

public IActionResult Create()
{
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
    if (ModelState.IsValid)
    {
        _context.Add(movie);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(movie);
}
  • The first (HTTP GET) Create action method displays the initial Create form.

  • The second ([HttpPost]) version handles the form post.

  • The second Create method (The [HttpPost] version) calls ModelState.IsValid to check whether the movie has any validation errors.

    • Calling this method evaluates any validation attributes that have been applied to the object.

    • If the object has validation errors, the Create method re-displays the form.

    • If there are no errors, the method saves the new movie in the database.

  • In our movie example, the form isn't posted to the server when there are validation errors detected on the client side.

    • the second Create method is never called when there are client-side validation errors.

Note: If you disable JavaScript in your browser, then submit the form with errors, you still get full validation without JavaScript, on the server-side!

But how does JavaScript know?

But how does JavaScript or jQuery know about the element names and what to validate?

A portion of the Create.cshtml view template is shown in the following markup:

<h4>Movie</h4>
<hr />
<div class="row">
<div class="col-md-4">
    <form asp-action="Create">
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Title" class="control-label"></label>
            <input asp-for="Title" class="form-control" />
            <span asp-validation-for="Title" class="text-danger"></span>
        </div>
        @*Markup removed for brevity.*@
  • The preceding markup is used by the action methods to display the initial form and to redisplay it in the event of an error.

  • The Input Tag Helper uses the DataAnnotations attributes and produces HTML attributes needed for jQuery Validation on the client side.

  • The Validation Tag Helper displays validation errors.

  • What's really nice about this approach is that neither the controller nor the Create view template knows anything about the actual validation rules being enforced or about the specific error messages displayed.

  • The validation rules and the error strings are specified only in the Movie class. These same validation rules are automatically applied to the Edit view and any other views templates you might create that edit your model.

  • When you need to change validation logic, you can do so in exactly one place by adding validation attributes to the model (in this example, the Movie class).

All validation logic will be defined in one place and used everywhere. This keeps the code very clean, and makes it easy to maintain and evolve. And it means that you'll be fully honoring the DRY principle.

Last updated