Verify that asp-validation-summary works

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 display input validation errors on the screen in Core. I didn't really understand the difference between the parameters that I could specify, so I checked it.

There are three possible values:

  • None
  • ModelOnly
  • All

As a result of examining how each of these differences works, the result is as follows:

Pre-preparation

For the time being, we will prepare for the operation. Most of them are redundant, so if you only want to see the results, see the second half of the article.

This validation assumes that you want to register the user in the form, so we will create a view model for the user. I put various items, but the contents do not matter anything because it is possible to verify if there is at least one. We'll check with DataAnnotation, so we'll set the Required and StringLength attributes. To see the difference in behavior, I just put 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, since asp-validation-summary is a view side story, the contents of each action are all the same code except for messages.

If IsAccepted is not checked, we are adding an error. The error is added to the error with a different key than the model and an empty key.

If there are no errors, display a successful registration message.

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 each test is done.

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 the user registration page for verification. If there is an error, specify None for asp-validation-summary as a parameter to display its contents. We also put the "Error Direct Entry" sentence in the div tag to see if the default error message is displayed.

Other code is not discussed in detail because it is the code that was automatically generated by scaffolding based on the model. (Some of them have been fixed by hand, but it has nothing to do with this verification.)

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

Also, asp-validation-summary displays the server verification 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");}
}*@

ValidateModelOnly.cshtml pages are only unless you specify ModelOnly for asp-validation-summary. The display text is the same as ValidateNone.cshtml peeking at.

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>

@* 省略 *@

ValidateAll.cshtml pages are almost identical except for specifying All for 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 the operation

None

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

Since "Error direct input" is displayed in the initial display state, it does not seem to be able to be used as a default error message. There are parameters that have been set to Required, so let's continue to perform the update process.

As the name of None, nothing is displayed if there is an error. The default error message remains intact, so there is unlikely a chance to set None directly and use it. If you have a chance to use it, do you want to dynamically set the value to asp-validation-summary and none if you don't want to see an error?

ModelOnly

Asp-validation-summary= The screen withModelOnly. I think that there are a lot of use scenes most because it comes out in the sample of the verification error and scaffolding.

Since the text of "Error direct input" that was placed in the div tag is not displayed, it seems that there is no problem even if you put it.

It is a state in which the registration process is performed and the error is displayed. The only messages displayed here are the default messages that were previously placed in the div tag and the error messages that occurred on the server side. Note, however, that if you do not have an empty key message on the server side, the message in the div tag will not appear.

On the server side, two error messages are put, but only the error with empty characters in the key is displayed. If you specify a key, it will be treated as an error in the property of the model with that name, so it does not appear in the asp-validation-summary. Instead, a message appears at any tag with the asp-validation-for attribute of the same name.

All

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

For some reason, the text of the embedded "error direct input" is displayed. I'm not sure why I don't see ModelOnly alone. It seems that embedding cannot be used in All for the time being.

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 want to specify All to summarize the error, It would be better to remove the asp-validation-for attribute set for each input field.

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

Summary

Asp-validation-summary had three parameters. You may want to use ModelOnly to make it easier to understand where the error is, or to eliminate 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 as you want to an empty key, so you don't have to combine strings to display multiple messages.

For All, if you want to collect error messages in one place, For None, set dynamically when you do not want an error message to appear for any reason. It is good to use it for the purpose of.