如何修改LabelFor以在必填字段上显示星号?

Bru*_*oLM 65 c# asp.net-mvc-3

我想创建一个扩展方法HtmlHelper,允许我创建LabelFor一个属性显示后面的星号,如果它是必填字段.我怎样才能做到这一点?

public class Foo
{
    [Required]
    public string Name { get; set; }
}

Html.LabelFor(o => o.Name) // Name*
Run Code Online (Sandbox Code Playgroud)

小智 121

您可以纯粹通过CSS将星号添加到必填字段.

首先,为它创建一个CSS类:

.required:after 
{
    content: "*";
    font-weight: bold;
    color: red; 
}
Run Code Online (Sandbox Code Playgroud)

这会将红色星号附加到具有"required"类的任何元素.

然后,在您的视图中,只需将新类添加到您的标签:

    @Html.LabelFor(m => m.Name, new { @class="required" })
Run Code Online (Sandbox Code Playgroud)

更好的可能是自定义HTML Helper,它可以识别字段是否具有[Required]属性,如果是,则添加requiredCSS类.

  • 对我来说不起作用,但以下是:`@ Html.LabelFor(m => m.Name,new {@ class ="required"})`加上你建议的风格.谢谢你让我走上了正确的道路. (6认同)

Jas*_*Cav 36

这是一篇描述如何执行此操作的博客文章.

为了给你一个从上面的网站修改的小例子(注意 - 我没有编译/测试过这个):

namespace HelpRequest.Controllers.Helpers
{
   public static class LabelExtensions
    {
        public static MvcHtmlString Label(this HtmlHelper html, string expression, string id = "", bool generatedId = false)
        {
            return LabelHelper(html, ModelMetadata.FromStringExpression(expression, html.ViewData), expression, id, generatedId);
        }

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
        public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, string id = "", bool generatedId = false)
        {
            return LabelHelper(html, ModelMetadata.FromLambdaExpression(expression, html.ViewData), ExpressionHelper.GetExpressionText(expression), id, generatedId);
        }

        internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string id, bool generatedId)
        {
            string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
            if (String.IsNullOrEmpty(labelText))
            {
                return MvcHtmlString.Empty;
            }
            var sb = new StringBuilder();
            sb.Append(labelText);
            if (metadata.IsRequired)
                sb.Append("*");

            var tag = new TagBuilder("label");
            if (!string.IsNullOrWhiteSpace(id))
            {
                tag.Attributes.Add("id", id);
            }
            else if (generatedId)
            {
                tag.Attributes.Add("id", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName) + "_Label");
            }

            tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
            tag.SetInnerText(sb.ToString());

            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我花了差不多一整天才发现你必须使用@ Html.MyFor(m => m.Name)而不是@ MyNamespace.MyFor(m => m.Name).所以这是对那些可能面临同样问题的人的小小贡献.;) (3认同)
  • `ModelMetadata.FromStringExpression(expression,html.ViewData)`用这个我可以检查`meta.IsRequired`并做我想做的事.谢谢你的回答. (2认同)

小智 21

我这样做是因为我的必填字段必须是动态的(在配置文件中定义)

在视图的末尾添加:

    <script type="text/javascript">
        $('input[type=text]').each(function () {
            var req = $(this).attr('data-val-required');
            if (undefined != req) {
                var label = $('label[for="' + $(this).attr('id') + '"]');
                var text = label.text();
                if (text.length > 0) {
                    label.append('<span style="color:red"> *</span>');
                }
            }
        });
    </script>
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,但只适用于输入[type = text]元素的样式.必需属性也可以作为<select>,<textarea>或其他元素输出.请考虑使用$('[data-val-required]')选择器. (4认同)
  • +1用于达到要求的更简单(虽然可以说是更脆弱)的方式.自定义HtmlHelper是一个更硬核,更好的解决方案,但我不喜欢使用反射来确定真正的IsRequired结果. (3认同)

Max*_*ime 20

这是我的解决方案基于Adam Tuliper的答案,但经过修改后可以使用Bootstrap并允许使用自定义属性.

using System;
using System.Linq;
using System.Web.Mvc;
using System.Linq.Expressions;
using System.ComponentModel;


public static class RequiredLabel
{
    public static MvcHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
        string labelText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();

        if (metaData.IsRequired)
            labelText += "<span class=\"required\">*</span>";

        if (String.IsNullOrEmpty(labelText))
            return MvcHtmlString.Empty;

        var label = new TagBuilder("label");
        label.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));

        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(htmlAttributes))
        {
            label.MergeAttribute(prop.Name.Replace('_', '-'), prop.GetValue(htmlAttributes).ToString(), true);
        }

        label.InnerHtml = labelText;
        return MvcHtmlString.Create(label.ToString());
    }

}
Run Code Online (Sandbox Code Playgroud)

然后,我从我的观点中这样称呼它:

@Html.RequiredLabelFor(model => model.Category, new { @class = "control-label col-md-3" })
Run Code Online (Sandbox Code Playgroud)

PS确保您不要忘记在视图中包含命名空间.

  • 感谢您在代码顶部放置正确的using语句.保存一些搜索对象的正确名称空间. (7认同)

Ada*_*SFT 13

在这里看到这篇文章 - 应该包含你需要的大部分内容 http://blogs.planetcloud.co.uk/mygreatdiscovery/post/Creating-tooltips-using-data-annotations-in-ASPNET-MVC.aspx

public static MvcHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
    var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

    string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
    string labelText = metaData.DisplayName ?? metaData.PropertyName ?? htmlFieldName.Split('.').Last();

    if (metaData.IsRequired)
        labelText += "<span class=\"required-field\">*</span>";

    if (String.IsNullOrEmpty(labelText))
        return MvcHtmlString.Empty;

    var label = new TagBuilder("label");
    label.Attributes.Add("for", helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));

    label.InnerHtml = labelText;
    return MvcHtmlString.Create(label.ToString());
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*rdi 5

使用 helper 将样式类添加到标签

public static MvcHtmlString RequiredLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var resolvedLabelText = metadata.DisplayName ?? metadata.PropertyName;
    if (!metadata.IsRequired)
    {
        return html.LabelFor(expression, resolvedLabelText, htmlAttributes);
    }

    var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    if (attributes == null)
    {
        return html.LabelFor(expression, resolvedLabelText, htmlAttributes);
    }

    const string requiredClass = "required-label";
    if (attributes.ContainsKey("class"))
    {
        var classList = attributes["class"].ToString().Split(' ').ToList();
        classList.Add(requiredClass);
        attributes["class"] = string.Join(" ", classList);
    }
    else
    {
        attributes.Add("class", requiredClass);
    }

    return html.LabelFor(expression, resolvedLabelText, attributes);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以设置类的样式:

.required-label::after { content : "*" }
Run Code Online (Sandbox Code Playgroud)