ASP.NET 7.0 Razor Pages中如何获取属性验证状态?
在ASP.NET 7.0 Razor Pages中结合Bootstrap 5.1显示服务端验证状态
要给Bootstrap表单控件添加is-invalid/is-valid类并匹配服务端验证状态,核心是获取对应字段在ModelStateDictionary中的完整键,尤其是处理嵌套属性或EditorTemplate场景时。以下是具体实现方案:
1. 自定义HtmlHelper扩展方法(复用性最高)
创建一个扩展方法,自动处理字段的完整路径,无需手动拼接嵌套属性键:
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewFeatures; public static class HtmlHelperValidationStateExtensions { public static string GetValidationStateClass(this IHtmlHelper htmlHelper, string propertyName = "") { // 获取字段的完整ModelState键(自动处理嵌套属性,如User.Email) var fullFieldName = htmlHelper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName); if (htmlHelper.ViewContext.ModelState.TryGetValue(fullFieldName, out var stateEntry)) { return stateEntry.ValidationState switch { ModelValidationState.Invalid => "is-invalid", ModelValidationState.Valid => "is-valid", _ => "" // 未验证状态不添加类 }; } return ""; } }
2. 普通Razor页面中使用
直接在表单控件的class中调用扩展方法,配合Bootstrap的反馈类:
<div class="mb-3"> <label asp-for="Email" class="form-label"></label> <input asp-for="Email" class="form-control @Html.GetValidationStateClass("Email")" /> <div class="invalid-feedback"> <span asp-validation-for="Email"></span> </div> </div>
3. EditorTemplate中处理嵌套属性
在EditorTemplate(如针对复杂模型User的模板User.cshtml)中,同样调用扩展方法,它会自动生成嵌套属性的完整键(如User.Email):
<!-- Views/Shared/EditorTemplates/User.cshtml --> <div class="mb-3"> <label asp-for="Email" class="form-label"></label> <input asp-for="Email" class="form-control @Html.GetValidationStateClass("Email")" /> <div class="invalid-feedback"> <span asp-validation-for="Email"></span> </div> </div> <div class="mb-3"> <label asp-for="Password" class="form-label"></label> <input asp-for="Password" class="form-control @Html.GetValidationStateClass("Password")" /> <div class="invalid-feedback"> <span asp-validation-for="Password"></span> </div> </div>
当在主页面调用@Html.EditorFor(m => m.User)时,扩展方法会自动识别嵌套路径,正确匹配ModelState中的验证状态。
4. 无扩展方法的直接实现(临时场景)
如果不想创建扩展方法,可在视图中直接编写逻辑:
@{ var fullFieldName = Html.ViewData.TemplateInfo.GetFullHtmlFieldName("Email"); string validationClass = ""; if (Html.ViewContext.ModelState.TryGetValue(fullFieldName, out var entry)) { validationClass = entry.ValidationState switch { ModelValidationState.Invalid => "is-invalid", ModelValidationState.Valid => "is-valid", _ => "" }; } } <input asp-for="Email" class="form-control @validationClass" /> <div class="invalid-feedback"> <span asp-validation-for="Email"></span> </div>
关键说明
ViewData.TemplateInfo.GetFullHtmlFieldName()是核心:它会根据当前视图/模板的上下文,生成与ModelState匹配的完整字段键,解决嵌套属性的路径问题。ModelValidationState有三种状态:Unvalidated(初始未提交状态)、Valid(验证通过)、Invalid(验证失败),仅在验证完成后添加对应样式类。
内容的提问来源于stack exchange,提问作者Michael Chen
相关产品推荐
相关产品推荐

