Razor Pages自定义TagHelper无法显示服务器端验证错误求助
问题原因
自定义的text-required-field标签助手在构建验证span时,没有主动读取ModelState中的错误信息并填充到span内容里。原生的asp-validation-for标签助手会自动完成这一步:它会从当前ViewContext的ModelState中查找对应字段的错误,然后将错误文本插入到span中,同时管理显示/隐藏的样式类。
解决方案
修改自定义TagHelper,注入ViewContext以访问ModelState,手动获取并填充验证错误信息,同时完善验证span的样式逻辑。
修改后的TagHelper代码
[HtmlTargetElement(tag: "text-required-field")] public class StringRequiredFieldHelper : TagHelper { // 注入ViewContext,用于访问ModelState [ViewContext] public ViewContext? ViewContext { get; set; } [HtmlAttributeName("asp-for")] public ModelExpression? For { get; set; } [HtmlAttributeName("asp-validation-for")] public ModelExpression? Validation { get; set; } [HtmlAttributeName("label-for")] public string? LabelName { get; set; } // 可选:支持自定义容器类 [HtmlAttributeName("container-class")] public string? ContainerClass { get; set; } = "form-group mx-2 my-2 w-full sm:w-1/2 md:w-1/3 lg:w-1/4"; public override void Process(TagHelperContext Context, TagHelperOutput Output) { var container = new TagBuilder("div"); // 设置容器类 container.AddCssClass(ContainerClass ?? string.Empty); // 构建Label标签 var label = new TagBuilder("label"); label.Attributes["for"] = For?.Name; label.AddCssClass("block"); label.InnerHtml.Append(LabelName ?? string.Empty); // 构建Input标签 var input = new TagBuilder("input"); input.Attributes["name"] = For?.Name; input.Attributes["id"] = For?.Name; input.Attributes["value"] = For?.Model?.ToString(); input.AddCssClass("form-input w-full bg-yellow-100 dark:bg-yellow-100 dark:text-black"); input.Attributes["type"] = "text"; // 构建验证Span标签 var validation = new TagBuilder("span"); validation.AddCssClass("text-red-600"); // 从ModelState获取错误信息 var validationMessage = string.Empty; if (ViewContext != null && Validation != null) { if (ViewContext.ModelState.TryGetValue(Validation.Name, out var modelStateEntry) && modelStateEntry.Errors.Any()) { validationMessage = modelStateEntry.Errors.First().ErrorMessage; validation.AddCssClass("field-validation-error"); } else { validation.AddCssClass("field-validation-valid"); } } // 设置验证span的属性和内容 validation.Attributes["data-valmsg-for"] = Validation?.Name; validation.Attributes["data-valmsg-replace"] = "true"; validation.InnerHtml.Append(validationMessage); // 组装所有元素 container.InnerHtml.AppendHtml(label); container.InnerHtml.AppendHtml(input); container.InnerHtml.AppendHtml(validation); Output.Content.SetHtmlContent(container); } }
关键修改点说明
- 注入ViewContext:通过
[ViewContext]属性注入当前视图的上下文,这样才能访问ModelState集合。 - 读取ModelState错误:检查对应字段的ModelState条目,提取第一条错误信息作为验证提示文本。
- 完善样式类逻辑:根据是否存在错误,动态添加
field-validation-error或field-validation-valid类,和原生标签助手的行为保持一致。 - 可选:容器类自定义:添加
container-class属性,让你可以灵活设置外层div的样式,和原表单结构保持一致。
使用修改后的TagHelper
<text-required-field asp-for="Record.Name" asp-validation-for="Record.Name" label-for="@RS_Relationships.name" container-class="form-group mx-2 my-2 w-full sm:w-1/2 md:w-1/3 lg:w-1/4"></text-required-field>
内容的提问来源于stack exchange,提问作者Joan Alexander
相关产品推荐
相关产品推荐

