asp.net-mvc 如何在 ASP MVC 中自定义 Html.ValidationMessageFor
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8380988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to customize Html.ValidationMessageFor in ASP MVC
提问by parleer
Is it possible to customize the Html.ValidationMessageFor method so that it produces different HTML?
是否可以自定义 Html.ValidationMessageFor 方法以生成不同的 HTML?
I want to do something similar to:
我想做类似的事情:
<div class="field-error-box">
<div class="top"></div>
<div class="mid"><p>This field is required.</p></div>
</div>
回答by archil
I am not sure if it's possible to use paragraph instead of default span, as it may make impossible for validation plugin to place error messages. But for div -s, thats easy - you could write custom html helper.
我不确定是否可以使用paragraph 而不是 default span,因为它可能使验证插件无法放置错误消息。但是对于 div -s,这很简单 - 您可以编写自定义 html 帮助程序。
Something along these lines (may need further testing/coding). You will need to include the namespace of this static extension method in your view, or put this into System.Web.Mvc.Htmldirectly.
沿着这些路线的东西(可能需要进一步测试/编码)。您需要在视图中包含此静态扩展方法的命名空间,或者System.Web.Mvc.Html直接将其放入。
public static class Validator
{
public static MvcHtmlString MyValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
TagBuilder containerDivBuilder = new TagBuilder("div");
containerDivBuilder.AddCssClass("field-error-box");
TagBuilder topDivBuilder = new TagBuilder("div");
topDivBuilder.AddCssClass("top");
TagBuilder midDivBuilder = new TagBuilder("div");
midDivBuilder.AddCssClass("mid");
midDivBuilder.InnerHtml = helper.ValidationMessageFor(expression).ToString();
containerDivBuilder.InnerHtml += topDivBuilder.ToString(TagRenderMode.Normal);
containerDivBuilder.InnerHtml += midDivBuilder.ToString(TagRenderMode.Normal);
return MvcHtmlString.Create(containerDivBuilder.ToString(TagRenderMode.Normal));
}
}
As you see, this uses default ValidationMessageFormethod, to not interfere with validation-plugin error message processing.
如您所见,这使用默认ValidationMessageFor方法,不会干扰验证插件错误消息处理。
And you use this simply, as default validation message helper
你可以简单地使用它,作为默认的验证消息助手
@Html.MyValidationMessageFor(model => model.SomeRequiredField)
回答by Yogev Smila
I used another way:
我用了另一种方式:
public static MvcHtmlString DivValidationMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
return MvcHtmlString.Create(htmlHelper.ValidationMessageFor(expression).ToString().Replace("span", "div"));
}
This way you can use the built in way, but replace the span with a div.
这样您就可以使用内置方式,但用 div 替换跨度。
If you need any other overloads of the function, just duplicate as necessary.
如果您需要该函数的任何其他重载,只需根据需要进行复制。
回答by saintedlama
You can implement your own ValidationMessageFor helper to emit your desired output or use some javascript to add/modify the rendered HTML code but the custom ValidationMessageFor implementation is the cleaner approach IMHO.
您可以实现自己的 ValidationMessageFor 助手以发出所需的输出或使用一些 javascript 添加/修改呈现的 HTML 代码,但自定义 ValidationMessageFor 实现是更简洁的方法恕我直言。
To implement your own ValidationMessageFor helper take a look at the ValidationExtensions.ValidationMessageFor and ValidationMessageHelper methods in the ASP.NET MVC source code.
要实现您自己的 ValidationMessageFor 助手,请查看 ASP.NET MVC 源代码中的 ValidationExtensions.ValidationMessageFor 和 ValidationMessageHelper 方法。
Implementation Hints
实施提示
Since GetFormContextForClientValidation is internal you have to work around that implementation by duplicating the internal functionality in your code:
由于 GetFormContextForClientValidation 是内部的,因此您必须通过复制代码中的内部功能来解决该实现:
FormContext formContext = htmlHelper.ViewContext.ClientValidationEnabled ? htmlHelper.ViewContext.FormContext : null;
Some other methods are private in ValidationExtensions like GetUserErrorMessageOrDefault you would need to duplicate that code too. What you can do to avoid duplicating code is to let ValidationExtentensions.ValidationMessageFor render the validation message string that is wrapped in a span and afterwards change the rendered string according to your requirements. Keep in mind that "null" is returned in case no error was found and that you'll need the data- HTML attributes in case you have unobtrusive JavaScript enabled.
其他一些方法在 ValidationExtensions 中是私有的,例如 GetUserErrorMessageOrDefault,您也需要复制该代码。为了避免重复代码,您可以做的是让 ValidationExtentensions.ValidationMessageFor 呈现包装在 span 中的验证消息字符串,然后根据您的要求更改呈现的字符串。请记住,如果未发现错误,将返回“null”,并且您将需要 data-HTML 属性,以防您启用了不显眼的 JavaScript。
You can download the ASP.NET MVC 3 source code from here
您可以从这里下载 ASP.NET MVC 3 源代码
回答by Hulvej
The only need for change of the default tag generation was in my case, that spans behavior results in anoying margin setups.
在我的情况下,唯一需要更改默认标签生成的是,跨越行为会导致令人讨厌的边距设置。
I resolved this by using 'display: block'
我通过使用“显示:块”解决了这个问题
Maybe this helps some people..
也许这对某些人有帮助..
回答by defstat
Maybe you can put that code
也许你可以把那个代码
string propertyName = ExpressionHelper.GetExpressionText(expression);
string name = helper.AttributeEncode(helper.ViewData.TemplateInfo.GetFullHtmlFieldName(propertyName));
if (helper.ViewData.ModelState[name] == null ||
helper.ViewData.ModelState[name].Errors == null ||
helper.ViewData.ModelState[name].Errors.Count == 0)
{
return MvcHtmlString.Empty;
}
on top of the answered function, so that the div doesn't appear on the form load.
在回答的函数之上,这样 div 就不会出现在表单加载中。
回答by Hyman Miller
I created ValidationMessageAsStringForwhich just returns the error message as string. It is basically a simplified version of ValidationMessageFor:
我创建的ValidationMessageAsStringFor只是将错误消息作为字符串返回。它基本上是以下的简化版本ValidationMessageFor:
public static MvcHtmlString ValidationMessageAsStringFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
var field = ExpressionHelper.GetExpressionText(expression);
string modelName = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(field);
if (!helper.ViewData.ModelState.ContainsKey(modelName))
{
return null;
}
var modelState = helper.ViewData.ModelState[modelName];
var modelErrors = (modelState == null) ? null : modelState.Errors;
var modelError = ((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors.FirstOrDefault(m => !String.IsNullOrEmpty(m.ErrorMessage)) ?? modelErrors[0];
if (modelError == null)
{
return null;
}
var errorMessage = GetUserErrorMessageOrDefault(helper.ViewContext.HttpContext, modelError, modelState);
return MvcHtmlString.Create(errorMessage);
}
private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
{
if (!string.IsNullOrEmpty(error.ErrorMessage))
{
return error.ErrorMessage;
}
if (modelState == null)
{
return null;
}
return modelState.Value?.AttemptedValue;
}
With this in place and after importing the namespace containing the new helper, just create the HTML code you need:
有了这个并导入包含新助手的命名空间后,只需创建您需要的 HTML 代码:
<div class="field-error-box">
<div class="top"></div>
<div class="mid"><p>@Html.ValidationMessageAsStringFor(m => m.FieldName)</p></div>
</div>
回答by shennyL
Yes, just use a metamodel for the field:
是的,只需为该字段使用元模型:
[MetadataType(typeof(YourMetaData))]
public partial class YOURCLASS
{
[Bind(Exclude = "objID")]
public class YourMetaData
{
[Required(AllowEmptyStrings = false, ErrorMessage = "Please enter a name")]
public object Name { get; set; }
}
}
Change your message at the ErrorMessage field :) Hope this help :)
在 ErrorMessage 字段更改您的消息 :) 希望这会有所帮助 :)

