代码之家  ›  专栏  ›  技术社区  ›  Darren Lewis

在ASP.NET MVC 2.0中为视图中的[必需]字段定义标记

  •  3
  • Darren Lewis  · 技术社区  · 14 年前

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

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

    5 回复  |  直到 14 年前
        1
  •  4
  •   Gregoire    14 年前

    您可以为此构建自己的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;
    }
    
        2
  •  3
  •   Stef Heyenrath Dariusz Woźniak    12 年前

    因此,如果您像这样使用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;
    }
    
        3
  •  2
  •   Faxanadu    14 年前

    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;
        }
    
        4
  •  1
  •   John Farrell    14 年前

    如果您使用的是格式完整的模板帮助程序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属性为真,会发生什么。内部对象.ascx:

    <%=propertu.IsRequired ? "*" : ""%>
    

    如果您不使用模板化的帮助程序,您就必须编写自己的html帮助程序。你的观点是什么?

        5
  •  0
  •   iuristona    12 年前

    我现在知道这个问题有点老了,但我正在使用jquery找到一个不引人注目的解决方案。

    我的目标是获取所有用datavalrequired属性标记的输入,然后设置它的label elementes marked with attribute for

    以下是示例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() + ' *');
    });