(C# ASP.NET Core) How to handle Server Side Validation

This article starts with a brief primer on server side validations and why they should be done. A simple model of just one property is used to explain the whole process - starting from setting the validation error messages to finally inserting validation tags to render the errors. We explain how "asp-validation-for" attributes can be used to display validation errors, and that too, respectively, for each property and at a location just adjacent to its FORM element(see the screenshot below), and also how the ASP.NET Core engine takes care of almost 99% of your work. We also explain how to, optionally, display a gist of all validation errors using the "asp-validation-summary" attribute.
(Rev. 19-Mar-2024)

Categories | About |     |  

Parveen,

A Primer on Server Side Validation

Server side validation is a pre-check of the POSTED form data before it is processed and passed to a database.

Even though client-side validation is sufficient in most cases, yet a second check may be needed on the server side for a confirmed assurance of the sanctity of data that is about to be passed to a database. Server side validations could almost be mandatory given the fact that client side validations could fail to trigger if javascript has been turned off by a user.

Server side validation is done through a c# code that runs in the OnPost handler.

Step 1 of 3: Set Validation Rules and Messages

Validation rules and error messages are set on the respective properties in the model itself.

Take the simplest case of a model with just one property on which we have set two validation rules and their respective error messages.

using System.ComponentModel.DataAnnotations;

public class User
{

  [Required(ErrorMessage = "name is required")]
  [MaxLength(15, ErrorMessage ="atmost 15 chars")]
  public String Name { get; set; }
}

Some common validation attributes are:

  1. Required
  2. MinimumLength
  3. RegularExpression
  4. RegularExpression
  5. Range
  6. StringLength
  7. Value types such as decimal, int, float, DateTime are, by nature, always required, so there are no [required] attributes for them.

For a complete list of validation attributes please refer Built-in validation attributes

Video Explanation

Please watch the following youtube video:

Step 2 of 3: Add Validation to the Razor Markup

This is a FORM that has an empty span linked to the Name property through the asp-validation-for attribute. This span can be styled with any CSS. It is internally used by ASP.NET Core for displaying validation errors.

Additionally, you can add an empty tag (say, a div) to show all the validation errors together at one place. For this the attribute asp-validation-summary="All" must be set as shown.


// index.cshtml razor markup file 

@page

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

@model MyRazorApp.Pages.IndexModel

  // validation summary for all errors 
  // managed entirely by ASP.NET Core 
  <div asp-validation-summary="All"></div>

<form method="POST">

  <table>

    <tr>

      <td>
        Name:
      </td>

      <td>
        <input asp-for="UserData.Name" type="text" />
      </td>

      <td>

        // empty span for validation 
        // it will be used by ASP.NET Core 
        // to display validation errors 
        <span asp-validation-for="UserData.Name" style="color:red"></span>

      </td>

    </tr>

    <tr>

      <td colspan="2" style="text-align:right;">

        <button type="submit">Send!</button>

      </td>

    </tr>

  </table>

</form>

Step 3 of 3: Validation Check on the Backing Class

Validation checks are performed entirely by the ASP.NET Core engine, and they take place on the basis of the validation attributes and error messages that you set on the various model properties.

The following is the single line of code that performs all validations and returns a false if ANY of them fails.

if (!ModelState.IsValid)
{

  // atleast one validation has failed 
  // return immediately and let 
  // ASP.NET Core show the errors 
  return Page();

}

Under such a situation stop any further processing and return from the OnPost handler. ASP.NET Core will render each error message wherever it sees an asp-validation-for attribute. It's that simple!

Here is a completed code

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.RazorPages;

using MyRazorApp.Models;

using System.Threading.Tasks;

namespace MyRazorApp.Pages
{

  public class IndexModel : PageModel
  {

    [BindProperty]
    public User UserData { get; set; }

    // OnPost handler 
    public async Task<IActionResult> OnPostAsync()
    {

      // server side validation checks are 
      // done by ASP.NET Core on the basis 
      // of validation attributes set on 
      // the model properties 
      if (!ModelState.IsValid)
      {

        // return immediately and let 
        // ASP.NET Core show the errors 
        return Page();

      }

      // any artificial delay due to 
      // database activity, say 
      await Task.Delay(100);

      // redirect to final destination 
      return RedirectToPage();

    }

  }

}


This Blog Post/Article "(C# ASP.NET Core) How to handle Server Side Validation" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.