我们有一个模型,其属性用 [Required] 装饰,非常适合验证。但是,我们想做的是在视图中用星号(或其他样式)标记这些必填字段,以表示在用户输入任何数据进行验证之前它们是必需的。
我似乎无法找到 MVC 框架中内置的任何东西来允许我这样做,因此想知道是否其他人已经解决了这个问题以及如何解决?
最终,我们要防止的是,如果我们随后从模型属性中删除 [Required],则需要在两个地方更改代码。
非常感谢
我们有一个模型,其属性用 [Required] 装饰,非常适合验证。但是,我们想做的是在视图中用星号(或其他样式)标记这些必填字段,以表示在用户输入任何数据进行验证之前它们是必需的。
我似乎无法找到 MVC 框架中内置的任何东西来允许我这样做,因此想知道是否其他人已经解决了这个问题以及如何解决?
最终,我们要防止的是,如果我们随后从模型属性中删除 [Required],则需要在两个地方更改代码。
非常感谢
您可以为此构建自己的 HtmlHelper 扩展:
public static string RequiredMarkFor<TModel, TValue>(this HtmlHelper html, Expression<Func<TModel, TValue>> expression)
{
if(ModelMetadata.FromLambdaExpression(expression, html.ViewData).IsRequired)
return "*";
else
return string.Empty;
}
Gregoire 和 Faxanadu 的解决方案的问题是始终显示“*”,当使用正常验证验证字段并且使用“Html.ValidationMessageFor()”时也是如此。
因此,如果您像这样使用 html 扩展名:
@Html.EditorFor(model => model.Email)
@Html.RequiredFieldFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
如果字段存在验证错误,您将看到重复的*。
我做了这个修改后的扩展,基于此,它还检查该字段是否经过验证。
private static Type[] RequiredTypes = new Type[] { typeof(CustomRequiredAttribute), typeof(RequiredAttribute) };
/// <summary>
/// Generate a <span class="field-validation-error">*<< element.
///
/// See http://koenluyten.blogspot.com/2011/06/denote-required-fields-in-aspnet-mvc-3.html
/// </summary>
public static MvcHtmlString RequiredFieldFor<TModel, TValue>(this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression, string validationMessage = "*")
{
// Get the metadata for the model
var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
string fieldName = metadata.PropertyName;
// Check if the field is required
bool isRequired = metadata
.ContainerType.GetProperty(fieldName)
.GetCustomAttributes(false)
.Count(m => RequiredTypes.Contains(m.GetType())) > 0;
// Check if the field is validated
bool isValidated = html.ViewData.ModelState[fieldName] != null;
// If the field is required and not validated; generate span with an asterix
if (isRequired && !isValidated)
{
var span = new TagBuilder("span");
span.AddCssClass("field-validation-error");
span.SetInnerText(validationMessage);
return MvcHtmlString.Create(span.ToString(TagRenderMode.Normal));
}
return null;
}
如果您在使用“ModelMetadata.FromLambdaExpression”时收到“无效参数”错误,请确保为 HtmlHelper 指定泛型类型参数。这是 Gregoire 解决方案的修订版:
public static string RequiredMarkFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).IsRequired)
return "*";
else
return string.Empty;
}
如果您使用的是完整表单模板化帮助程序 EditorFor 和 DisplayFor,您需要自定义您自己的 Object.ascx 版本。
布拉德威尔逊有一篇很棒的博客文章概述了这一点:
ModelMetadata 上的 IsRequired 属性会发生什么情况。在 Object.ascx 内部:
<%=propertu.IsRequired ? "*" : ""%>
如果您不使用模板化助手,则必须编写自己的 html 助手。你的观点是什么样的?
我现在的问题有点老了,但我正在努力使用 jquery 提供一个不引人注目的解决方案。
我的目标是让所有输入都标记有 data-val-required 属性,然后将其标签元素设置为标记为
这是示例 jquery 代码:
$('[data-val-required]').each(function() {
var $label = $('label[for=' + this.name + ']');
//from here we can manipulate the label element
$label.css('font-weight', 'bold');
$label.text($label.text() + ' *');
});