如何修改 LabelFor 以在所需字段上显示星号?

我想为 HtmlHelper创建一个扩展方法,它允许我创建一个 LabelFor属性,如果它是一个必填字段,它后面会显示一个星号。我该怎么做?

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


Html.LabelFor(o => o.Name) // Name*
84099 次浏览

看看这个帖子-应该包含你需要的大部分内容 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());
}

下面是一个 博客文章,它描述了如何做到这一点。

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

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));
}
}
}

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

在视图末尾添加:

    <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>

您可以纯粹通过 CSS 向必填字段添加星号。

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

.required::after
{
content: "*";
font-weight: bold;
color: red;
}

这将在具有“必需”类的任何元素后面附加一个红色星号。

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

    @Html.LabelFor(m => m.Name, new { @class="required" })

更好的可能是一个定制的 HTML Helper,它可以识别字段是否具有[必需]属性,如果具有,则添加 required CSS 类。

这里是我的解决方案基于 Adam Tuliper 的回答,但修改工作与 鞋带,也允许使用 自定义属性

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


}

然后,我这样称呼它:

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

附注: 确保不要忘记在视图中包含名称空间。

使用 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);
}

然后你就可以给这门课设计风格了:

.required-label::after { content : "*" }

我通过其他一些帖子把它们拼凑起来:

它对我很有用,因为标签 for 后面跟着一个输入和一个 span (标签的输入和验证 span)

input[data-val-required]+span:before {
content: "*";
font-weight: bold;
color: red;
position:relative;
top:-34px;
left:-12px;
font-size:14pt;
}

基于上面的回答,雷纳托 · 齐藤附上了评论,并添加了 $(文档)。准备好并检查,以确保我们没有添加多个星号(出于某种原因,我的一些字段中出现了这个问题) ,我有以下内容:

// Add asterisks to required fields
$(document).ready(function() {
$("[data-val-required]").each(function () {
var label = $('label[for="' + $(this).attr("id") + '"]');
var asterisksHtml = '<span style="color:red">&nbsp;*</span>';
if (label.text().length > 0 && label.html().indexOf(asterisksHtml) === -1) {
label.append(asterisksHtml);
}
});
});

使用保留内部化/翻译标签和 html 属性的助手扩展,在强制字段(通过数据注释[必需]定义)后面添加一个修饰的字形图标

1. 创建文件夹“ Helpers”并添加一个新控制器“ Helper.cs”

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


namespace WIPRO.Helpers
{
public static class Helpers
{
public static MvcHtmlString LabelForRequired<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string translatedlabelText, 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 = translatedlabelText + "<span class=\"required\" style=\"color:orange;\"> <span style=\"font-size: 0.4em; vertical-align: super;\" class=\"glyphicon glyphicon-asterisk\" data-unicode=\"270f\"></span></span>";


}
else
{
labelText = translatedlabelText;


}


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());


}


}


}

2. 在你看来

@using WIPRO.Helpers


@Html.LabelForRequired(model => model.Test,"Translated text", htmlAttributes: new { @class = "control-label col-md-2" })

取代了

        @Html.LabelFor(model => model.Test,"Translated text", htmlAttributes: new { @class = "control-label col-md-2" })

希望能有所帮助; -)

虽然这不需要修改 LabelFor,但它是我能想到的最简单的,只需要在 ViewModel 中添加一行:

public class FooViewModel
{
[Required(ErrorMessage = "Name is required")]
[Display(Name ="Name*")]
public string Name { get; set; }
}


Html.LabelFor(o => o.Name)

最好的工作为我在 MVC 与多领域类型

$('input[type=text], input[type=password], input[type=email], input[type=tel], select').each(function () {
var req = $(this).attr('data-val-required');
if (undefined != req) {
var label = $('label[for="' + $(this).attr('name') + '"]');
var text = label.text();
if (text.length > 0) {
label.append('<span style="color:red"> *</span>');
}
}
});

我想创建一个 Label,它在需要属性时显示一个星号。但是不知为何,即使 [Required]属性已经设置并且在模型验证中工作,metadata.IsRequired属性也总是返回 false。所以我用了 AssociatedMetadataTypeTypeDescriptionProvider

public static MvcHtmlString CustomLabelFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, object htmlAttributes = null)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var descriptor = new AssociatedMetadataTypeTypeDescriptionProvider(metadata.ContainerType).GetTypeDescriptor(metadata.ContainerType).GetProperties().Find(metadata.PropertyName, true);
var required = (new List<Attribute>(descriptor.Attributes.OfType<Attribute>())).OfType<RequiredAttribute>().FirstOrDefault();


//get the normal labelfor
var label = htmlHelper.LabelFor(expression, htmlAttributes);


//create the extra span with the asterix in there is a required property
if (required != null)
{
var span = new TagBuilder("span");
span.MergeAttribute("class", "text-danger font-weight-bold");


//render the span
StringBuilder sb = new StringBuilder();
sb.Append(span.ToString(TagRenderMode.StartTag));
sb.Append("*");
sb.Append(span.ToString(TagRenderMode.EndTag));


return MvcHtmlString.Create(label.ToHtmlString() + " " + sb.ToString());
}
else
{
return label;
}
}

用法

@Html.CustomLabelFor(m => m.Title)

发布一个通用的解决方案:

下面是使用 Bootstrap 的一般格式:

<div class="form-group row">
<label class="col-md-3 label-control" asp-for="FacilityCode"></label>
<div class="col-md-9">
<input asp-for="FacilityCode" class="form-control" placeholder="@Localizer["Facility Code"]" />
<span asp-validation-for="FacilityCode" class="text-danger"></span>
</div>
</div>

下面是默认情况下生成的代码 TagHelper:

<div class="form-group row">
<label class="col-md-3 label-control" for="FacilityCode">Example Label </label>
<div class="col-md-9">
<input class="form-control" placeholder="Facility Code" type="text" data-val="true" data-val-length="The field Institution (Community) must be a string with a maximum length of 5." data-val-length-max="5" data-val-required="The Institution (Community) field is required." id="FacilityCode" maxlength="5" name="FacilityCode" value="12345">
<span class="text-danger field-validation-valid" data-valmsg-for="FacilityCode" data-valmsg-replace="true"></span>
</div>
</div>

我需要的是将 <span style="color:red;">*</span>附加到所有必需的字段,而不是到处使用 TagHelper

// append red star to required fields
$(document).ready(function () {
$('input[data-val-required]')
.closest(".form-group")
.find("label.label-control")
.append("<span style='color:red;'>*</span>");
});