在ASP.NET MVC 2.0中的View中为[Required]字段定义标记

时间:2010-06-04 14:03:34

标签: asp.net-mvc data-annotations requiredfieldvalidator

我们有一个模型,其属性用[Required]修饰,非常适合验证。但是,我们要做的是在视图中用星号(或其他一些样式)标记这些必填字段,以表示在用户输入任何数据进行验证之前需要它们。

我似乎无法在MVC框架中找到任何内容以允许我这样做,因此想知道其他人是否已经解决了这个以及如何解决这个问题?

最终我们要防止的是,如果我们随后从模型属性中删除[Required],则需要在两个位置更改代码。

非常感谢

5 个答案:

答案 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 &lt;span class="field-validation-error"&gt;*&lt;&lt; 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有一篇很棒的博客文章,其中概述了这一点:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html

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() + ' *');
});