我们有一个模型,其属性用[Required]修饰,非常适合验证。但是,我们要做的是在视图中用星号(或其他一些样式)标记这些必填字段,以表示在用户输入任何数据进行验证之前需要它们。
我似乎无法在MVC框架中找到任何内容以允许我这样做,因此想知道其他人是否已经解决了这个以及如何解决这个问题?
最终我们要防止的是,如果我们随后从模型属性中删除[Required],则需要在两个位置更改代码。
非常感谢
答案 0 :(得分:4)
您可以为此构建自己的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;
}
答案 1 :(得分:3)
Gregoire和Faxanadu解决方案的问题是始终显示“*”,同样在使用正常验证验证字段并使用'Html.ValidationMessageFor()'时。
因此,如果你使用这样的html扩展名:
@Html.EditorFor(model => model.Email)
@Html.RequiredFieldFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
如果字段有验证错误,您会看到重复的 * 。
我已根据this制作了此修改后的扩展程序,该扩展程序还会检查字段是否已经过验证。
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;
}
答案 2 :(得分:2)
如果在使用“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;
}
答案 3 :(得分:1)
如果您使用完整形式模板化助手EditorFor和DisplayFor,则需要自定义自己的Object.ascx版本。
Brad Wilson有一篇很棒的博客文章,其中概述了这一点:
ModelMetadata上的IsRequired属性会发生什么?在Object.ascx里面:
<%=propertu.IsRequired ? "*" : ""%>
如果您不使用模板化帮助程序,则必须编写自己的html帮助程序。你的观点是什么样的?
答案 4 :(得分:0)
我现在的问题有点老了,但我正在尝试使用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() + ' *');
});