Check the behavior of asp-validation-summary

Page updated :

Environment

Visual Studio
  • Visual Studio 2019
ASP.NET Core
  • 3.0
  • 3.1

At first

ASP.NET There is a way to use asp-validation-summary as a way to get input value validation errors to appear on the screen. I did not understand the difference of the parameter which can be specified well, so I checked it.

There are three values that can be specified:

  • None
  • ModelOnly
  • All

I've looked at how each of these differences works.

Pre-preparation

For now, we'll prepare below to verify the behavior. Most of them are made redundant, so if you just want to see the results, see the second part of the article.

This validation assumes that you register the user in the form, so we will create a user's view model. I put various items, but the contents can be anything because i can verify if there is at least one. DataAnnotation checks, so you set the attributes of Required and StringLength. To see the difference in behavior, I'm just putting in an extra IsAccepted.

** Models/UserViewModel **

using System;
using System.ComponentModel.DataAnnotations;

namespace ValidationSummaryTest.Models
{
  public class UserViewModel
  {
    [Required]
    [StringLength(20)]
    public string ID { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    // 省略

    [Required]
    public bool IsAccepted { get; set; }
  }
}

To examine the three values of asp-validation-summary, create each action. However, asp-validation-summary is a view-side story, so the contents of each action are all the same code except the message.

If IsAccepted is not checked, an error has been added. The error is a different key specification than the model and an error with an empty key.

Displays a successful registration message if there are no errors.

HomeController.cs

public IActionResult ValidateNone() => View();

[HttpPost]
public IActionResult ValidateNone(UserViewModel model)
{
  if (model.IsAccepted == false)
  {
    ModelState.AddModelError("PropertyName1", "プロパティに依存するエラー (None)");
    ModelState.AddModelError("", "空のキーエラー (None)");
  }
  if (ModelState.IsValid == false) return View(model);
  ViewData["Message"] = "正常に登録しました。";
  return View(model);
}

public IActionResult ValidateModelOnly() => View();

[HttpPost]
public IActionResult ValidateModelOnly(UserViewModel model)
{
  if (model.IsAccepted == false)
  {
    ModelState.AddModelError("PropertyName1", "プロパティに依存するエラー (ModelOnly)");
    ModelState.AddModelError("", "空のキーエラー (ModelOnly)");
  }
  if (ModelState.IsValid == false) return View(model);
  ViewData["Message"] = "正常に登録しました。";
  return View(model);
}

public IActionResult ValidateAll() => View();

[HttpPost]
public IActionResult ValidateAll(UserViewModel model)
{
  if (model.IsAccepted == false)
  {
    ModelState.AddModelError("PropertyName1", "プロパティに依存するエラー (All)");
    ModelState.AddModelError("", "空のキーエラー (All)");
  }
  if (ModelState.IsValid == false) return View(model);
  ViewData["Message"] = "正常に登録しました。";
  return View(model);
}

index.cshtml adds a link to the page where you want to test each.

index.cshtml

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<ul>
  <li><a asp-action="ValidateNone">ValidateNone</a></li>
  <li><a asp-action="ValidateModelOnly">ValidateModelOnly</a></li>
  <li><a asp-action="ValidateAll">ValidateAll</a></li>
</ul>

This is a user registration page for verification. If there is an error, asp-validation-summary is specified as none as the parameter to display the contents. It also includes "error direct input" text in the div tag to see if the default error message is displayed.

Other code is based on the model and is generated automatically by scaffolding, so i won't go into detail. (Some of them have been modified by hand, but this verification has nothing to do with it.)

There is a span tag with the asp-validation-for attribute next to each input item (input tag). This is a tag (attribute) for displaying an error message for each input item. Regardless of the parameter specified in asp-validation-summary, an error message is always displayed in that location if there is an error.

The asp-validation-summary also displays the server validation results, so the client validation process (_ValidationScriptsPartial) comments out.

ValidateNone.cshtml

@model ValidationSummaryTest.Models.UserViewModel

@{
  ViewData["Title"] = "ValidateNone";
}

<h1>ValidateNone</h1>

<h4>UserViewModel</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="ValidateNone">
    
      <div asp-validation-summary="None" class="text-danger">エラー直接入力</div>
      
      <div class="form-group">
        <label asp-for="ID" class="control-label"></label>
        <input asp-for="ID" class="form-control" />
        <span asp-validation-for="ID" class="text-danger"></span>
      </div>
      <div class="form-group">
        <label asp-for="Name" class="control-label"></label>
        <input asp-for="Name" class="form-control" />
        <span asp-validation-for="Name" class="text-danger"></span>
      </div>
      
      @* 省略 *@
      
      <div class="form-group form-check">
        <label class="form-check-label">
          <input class="form-check-input" asp-for="IsAccepted" /> @Html.DisplayNameFor(model => model.IsAccepted)
        </label>
      </div>
      <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
      </div>
    </form>
  </div>
</div>

<div>
  <a asp-action="Index">Back to List</a>
</div>

@* サーバーのエラーを表示したいのでコメントアウト *@
@*@section Scripts {
  @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}*@

The validateModelOnly.cshtml page is not based on asp-validation-summary except that modelonly is specified. It is the same as ValidateNone.cshtml by peeping at the display text.

ValidateModelOnly.cshtml

@model ValidationSummaryTest.Models.UserViewModel

@{
  ViewData["Title"] = "ValidateModelOnly";
}

<h1>ValidateModelOnly</h1>

<h4>UserViewModel</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="ValidateModelOnly">
      <div asp-validation-summary="ModelOnly" class="text-danger">エラー直接入力</div>
      
      @* 省略 *@

    </form>
  </div>
</div>

@* 省略 *@

The validateAll.cshtml page is similar to the other except that it specifies All in asp-validation-summary.

ValidateAll.cshtml

@model ValidationSummaryTest.Models.UserViewModel

@{
  ViewData["Title"] = "ValidateAll";
}

<h1>ValidateAll</h1>

<h4>UserViewModel</h4>
<hr />
<div class="row">
  <div class="col-md-4">
    <form asp-action="ValidateAll">
      <div asp-validation-summary="All" class="text-danger">エラー直接入力</div>
    </form>

    @* 省略 *@
  </div>
</div>

@* 省略 *@

Check operation

None

After you create the program, try to check the behavior. is an asp-validation-summary=None screen.

It is not available as a default error message because it is displayed as "Error Direct Input" in the initial display state. There are parameters that set Required, so let's continue to perform the update process.

As the name Of None says, no errors are displayed. The default error message remains intact, so there is no chance you will have a chance to set and use None directly. If you have a chance to use it, do you want to make the value set to asp-validation-summary dynamic and none if you don't want to see an error?

ModelOnly

asp-validation-summary=ModelOnly is the specified screen. I think that there are a lot of situations of use most because it comes out in the sample and scaffolding of the verification error.

Because the text of "Error direct input" which was put in the div tag is not displayed, it seems to be no problem even if I put it.

It is the state that I tried to display the error by performing the registration process. The only messages that appear here are the default messages that were previously placed in the div tag and error messages that occurred on the server side.

The server has two error messages, but only errors with empty characters in the key are displayed. If you specify a key, it is treated as an error in the property of the model with that name, so it does not appear in the asp-validation-summary. Instead, if there is a tag with the asp-validation-for attribute of the same name, a message is displayed in that place.

All

Asp-validation-summary=All is the specified screen.

For some reason, the embedded "error direct input" text is displayed. I'm not sure why ModelOnly just doesn't show up. For now, all can't use embedding.

It is a screen after the update process is performed as it is. Error messages for all input fields (properties) are displayed in a list. Each input field also displays an error message, so if you specify All to summarize the errors, You should remove the asp-validation-for attribute that you set for each input item.

You can also see error messages that you added on the server side. You can also see that you are viewing an error with a key.

Summary

asp-validation-summary had three parameters: It's a good idea to use ModelOnly to make it easier to understand where the error is, and to avoid duplication. Note that the only message displayed in asp-validation-summary is a message with an empty key.

By the way, you can add as many messages to an empty key, so you don't need to combine strings to display multiple messages.

For All, use if you want to collect error messages in one place, Set none dynamically when there is a timing when you do not want to display an error message for any reason, It is better to use for the purpose of.