There are times where you may want to display custom validation error messages in MVC.  As for me, I’m not a huge fan of the classic ValidationSummary HTML helper.  I will still annotate my data model, but I want the errors to have a better presentation in the UI. Occasionally, I may want to display one error at a time.  In order to do all of this, there’s a few steps that need to be implemented.

Razor

First, we need to “dress” our error message.  This could be wrapping it in a <div /> tag or placing it in a specific location on the page, etc.  Regardless, we dictate where and how we want the message displayed.  To do this use the following code:

@Html.ValidationSummary(true)

This will print out our custom error message(s).  Notice we supplied true for the overloaded method toexcludePropertyErrors.  This will temporarily “hide” the errors generated by the data model annotations.  Note, that the validation may still fail – this doesn’t disable validation – it simply doesn’t show the error messages from the data model.  Now we need to supply the error(s).

Adding Custom Errors

Our action may look something like the following:

public ActionResult Submit(MyModel model)
{
    if (ModelState.IsValid)
    {
        // Do something with the valid data
    }
    else
    {
        // Show only first error
        ModelState.AddModelError("", ModelState.Values.SelectMany(v => v.Errors).First().ErrorMessage);
  
        // Add custom error
        ModelState.AddModelError("", "My custom error message");
    }
 
    return View();
}

The previous code shows two alternatives for showing custom errors: 1) show only the first error of the validation summary; and, 2) show a custom message.

The first scenario is for when considering UI and presentation, you may only want to show one error at a time.  The LINQ gathers all validation errors, then returns only the first one.  This keeps the UI simple, clean and concise.  However, remember, if there are multiple validation errors, the user may have to resubmit the form multiple times.  Take this into consideration.

The second scenario is for, again, when you want to supply a fully customized message.

There are multiple overloads for ModelState.AddModelError, but most take two arguments.  The first argument is of typestring and is for the targeted property.  Two things to note for this:

  1. Yes, I can manually add additional validation errors to a model’s property by simply providing the property name here.
  2. Remember in the previous section we supplied true for the Html.ValidationSummary to exclude property errors?  By not supplying anything here except an empty string, the Html.ValidationSummary in our Razor will only show all errors that do not belong to a specific property – such as in this case.
The second argument for ModelState.AddModelError is of either type string or Exception.  You can supply an Exception (this is useful if you would like to wrap your logic in a Try/Catch block) or a custom message as a string, as we did in the second error message above.