如何解决对所有无效属性使用单个错误消息模板
想象一个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";
}
解决方法
我使用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>
如果您不想使用上述方法,也可以从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-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获取客户端验证结果,然后生成新的错误消息。
因此,我认为您可以尝试使用第一种方法(使用错误消息和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; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。