对所有无效属性使用单个错误消息模板
Use single error message template for all invalid properties
想象一个 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
?
编辑:
例如,在视图中显示错误之前,像这样更改错误消息:
@foreach (var error in modelStateErrors)
{
error.text = "Fill it";
}
您可以使用验证摘要(请参阅: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; }
I know I can use ErrorMessage for each of them separately, but its not
logical! is there any short way to show a specific massage for all of
invalid ModelStates?
关于这个问题,我认为最简单的显示错误信息的方法是使用ErrorMessage,如果你想把它们一起显示,你可以使用asp-validation-summary属性,像这样:
<div asp-validation-summary="All" class="text-danger"></div>
如果不想使用上述方法,也可以从ModelState字典中获取无效字段,然后,re-generate报错信息。代码如下:
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-for
和asp-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>
输出如下:
[注意]以上方法是服务器端验证。如果要使用客户端验证实现相同的行为,则必须使用 JavaScript 获取客户端验证结果,然后生成新的错误消息。
所以,在我看来,我建议您可以尝试使用第一种方法(使用 Error Message 和 asp-validation-summary
)来显示错误消息,并通过为每个属性分隔符使用 Error Message,用户可以更容易理解验证规则。
我创建了一个带有 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);
}
}
如果您不想对每个 Razor 页面进行更改,您可以使用页面过滤器自动清除和重命名错误消息。
这是一个页面过滤器示例:
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()));
想象一个 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
?
编辑:
例如,在视图中显示错误之前,像这样更改错误消息:
@foreach (var error in modelStateErrors)
{
error.text = "Fill it";
}
您可以使用验证摘要(请参阅: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; }
I know I can use ErrorMessage for each of them separately, but its not logical! is there any short way to show a specific massage for all of invalid ModelStates?
关于这个问题,我认为最简单的显示错误信息的方法是使用ErrorMessage,如果你想把它们一起显示,你可以使用asp-validation-summary属性,像这样:
<div asp-validation-summary="All" class="text-danger"></div>
如果不想使用上述方法,也可以从ModelState字典中获取无效字段,然后,re-generate报错信息。代码如下:
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-for
和asp-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>
输出如下:
[注意]以上方法是服务器端验证。如果要使用客户端验证实现相同的行为,则必须使用 JavaScript 获取客户端验证结果,然后生成新的错误消息。
所以,在我看来,我建议您可以尝试使用第一种方法(使用 Error Message 和 asp-validation-summary
)来显示错误消息,并通过为每个属性分隔符使用 Error Message,用户可以更容易理解验证规则。
我创建了一个带有 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);
}
}
如果您不想对每个 Razor 页面进行更改,您可以使用页面过滤器自动清除和重命名错误消息。
这是一个页面过滤器示例:
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()));