对所有无效属性使用单个错误消息模板

问题描述

想象一个razor page和一个Form,其中有许多输入由用户填充。

使用post方法来验证这样发布的模型:

public IActionResult OnPost()
{
     if (!ModelState.IsValid)
     {
        return Page(model);
     }
}

例如,如果该模型的3个属性(名称分别为:a,b,c)无效,则返回剃刀视图并显示错误(由于每个属性为asp-validation-for),如下所示:

The a field is required.
The b field is not a valid e-mail address.
The c field is required.

我想为所有这些人显示特定错误:

This Input is not valid.
This Input is not valid.
This Input is not valid.

我知道我可以分别为每个使用(ErrorMessage =""),但是在逻辑上不合逻辑!有什么方法可以显示针对所有无效ModelStates的特定按摩?

编辑:

例如,在View中显示错误之前,请像这样更改其错误消息:

@foreach (var error in modelStateErrors)
{
    error.text = "Fill it";
}

enter image description here

解决方法

我使用ModelState的扩展方法创建了一个解决方案。
基本上,它会从状态中删除所有错误,然后将它们添加回所需的消息中。

在您的命名空间中创建一个ModelStateExtensions.cs

public static class ModelStateExtensions
{
    public static void SetAllErrorMessages(this ModelStateDictionary modelState,string errorMessage)
    {
        foreach (var state in modelState)
        {
            if (state.Value.Errors.Count > 0)
            {
                modelState.Remove(state.Key);
                modelState.AddModelError(state.Key,errorMessage);
            }
        }
    }
}

然后,如果您的ModelState无效,则可以在返回页面之前转换消息:

public IActionResult OnPost()
{
     if (!ModelState.IsValid)
     {
        ModelState.SetAllErrorMessages("Your message here");
        return Page(model);
     }
}
,

我知道我可以分别对每个错误消息使用ErrorMessage,但不能 合乎逻辑!有没有什么短方法可以显示针对所有 无效的ModelState?

对于此问题,我认为显示错误消息的最简单方法是使用ErrorMessage,如果要同时显示它们,则可以使用asp-validation-summary属性,如下所示:

<div asp-validation-summary="All" class="text-danger"></div>

enter image description here

如果您不想使用上述方法,也可以从ModelState字典中获取无效的字段,然后重新生成错误消息。像这样的代码:

    public IActionResult OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            //get the new error message,you could also get all inValid fields.
            var messages = ModelState.Keys
                    .SelectMany(key => ModelState[key].Errors.Select(x => string.Format("The {0} is invalid",key)))
                    .ToList();
            ViewData["message"] = messages; //transfer the error message to the view

            return Page();
        }
         return  RedirectToPage("./Index");
      }

查看代码(显示错误消息(不使用asp-validation-forasp-validation-summary):

        <div class="form-group">
            @if (ViewData["message"] != null)
            {
                foreach (var item in (List<string>)ViewData["message"])
                { 
                    <span class="text-danger">@item</span><br/>
                }
            }
            <div id="debug">

            </div>
        </div>

输出如下:

enter image description here

[注]上面的方法是服务器端验证。如果要使用客户端验证来实现相同的行为,则必须使用JavaScript获取客户端验证结果,然后生成新的错误消息。

因此,我认为您可以尝试使用第一种方法(使用错误消息和asp-validation-summary)显示错误消息,并且通过对每个属性分隔符使用错误消息,用户可以更容易理解验证规则。

,

如果不想对每个剃刀页面进行更改,则可以使用页面过滤器自动清除并重命名错误消息。

以下是页面过滤器的示例:

public class ModelStatePageFilter : IPageFilter
{
    public void OnPageHandlerExecuted(PageHandlerExecutedContext ctx) { }

    public void OnPageHandlerExecuting(PageHandlerExecutingContext ctx)
    {
        foreach (var (k,v) in ctx.ModelState
            .Where(x => x.Value.ValidationState == ModelValidationState.Invalid))
        {
            v.Errors.Clear();
            v.Errors.Add("This Input is not valid.");
        }
    }

    public void OnPageHandlerSelected(PageHandlerSelectedContext ctx) { }
}

您需要在Startup.ConfigureServices中注册此页面过滤器。这是如何执行此操作的示例:

services.AddRazorPages()
    .AddMvcOptions(o => o.Filters.Add(new ModelStatePageFilter()));
,

您可以使用“验证摘要”(请参见:https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms?view=aspnetcore-3.1#the-validation-tag-helpers)。

@model RegisterViewModel

<form asp-controller="Demo" asp-action="RegisterValidation" method="post">
    <div asp-validation-summary="ModelOnly"></div>
    Email:  <input asp-for="Email" /> <br />
    <span asp-validation-for="Email"></span><br />
    Password: <input asp-for="Password" /><br />
    <span asp-validation-for="Password"></span><br />
    <button type="submit">Register</button>
</form>

如果要更改显示的错误消息,可以在ViewModel中进行:

[Required(ErrorMessage = "This Input is invalid")]
public string Email { get; set; }

[Required(ErrorMessage = "This Input is invalid")]
public string Password{ get; set; }

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...