我如何覆盖@ Html.LabelFor模板?
我有一个简单的字段forms
<div class="field fade-label"> @Html.LabelFor(model => model.Register.UserName) @Html.TextBoxFor(model => model.Register.UserName) </div>
这导致:
<div class="field fade-label"> <label for="Register_UserName">Username (used to identify all services, from 4 to 30 chars)</label> <input type="text" value="" name="Register.UserName" id="Register_UserName"> </div>
但我想要LabelFor
代码附加一个<span>
里面,所以我可以结束了:
<label for="Register_UserName"> <span>Username (used to identify all services, from 4 to 30 chars)</span> </label>
我该怎么做?
所有示例都使用EditorTemplates
但这是一个LabelFor
。
你可以通过创build你自己的HTML帮手来做到这一点。
http://www.asp.net/mvc/tutorials/creating-custom-html-helpers-cs
您可以通过下载ASP.Net MVC的源代码来查看LabelFor <>的代码,并将其修改为一个自定义帮助程序。
答案由balexandre添加
public static class LabelExtensions { public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes) { return LabelFor(html, expression, new RouteValueDictionary(htmlAttributes)); } public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IDictionary<string, object> htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); string htmlFieldName = ExpressionHelper.GetExpressionText(expression); string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); if (String.IsNullOrEmpty(labelText)) { return MvcHtmlString.Empty; } TagBuilder tag = new TagBuilder("label"); tag.MergeAttributes(htmlAttributes); tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); TagBuilder span = new TagBuilder("span"); span.SetInnerText(labelText); // assign <span> to <label> inner html tag.InnerHtml = span.ToString(TagRenderMode.Normal); return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal)); } }
LabelFor是扩展方法(静态),因此不能被覆盖。 你需要创build自己的Html Helper Extension方法来实现你所需要的。
我扩展了balealexandre的答案,并添加了指定HTML的能力,以便在标签文本之前和之后都包含这两个字符。 我添加了一堆方法重载和评论。 我希望这可以帮助人们!
也从这里收集信息: 使用Html帮手的标签内的Html
namespace System.Web.Mvc.Html { public static class LabelExtensions { /// <summary>Creates a Label with custom Html before the label text. Only starting Html is provided.</summary> /// <param name="startHtml">Html to preempt the label text.</param> /// <returns>MVC Html for the Label</returns> public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml) { return LabelFor(html, expression, startHtml, null, new RouteValueDictionary("new {}")); } /// <summary>Creates a Label with custom Html before the label text. Starting Html and a single Html attribute is provided.</summary> /// <param name="startHtml">Html to preempt the label text.</param> /// <param name="htmlAttributes">A single Html attribute to include.</param> /// <returns>MVC Html for the Label</returns> public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml, object htmlAttributes) { return LabelFor(html, expression, startHtml, null, new RouteValueDictionary(htmlAttributes)); } /// <summary>Creates a Label with custom Html before the label text. Starting Html and a collection of Html attributes are provided.</summary> /// <param name="startHtml">Html to preempt the label text.</param> /// <param name="htmlAttributes">A collection of Html attributes to include.</param> /// <returns>MVC Html for the Label</returns> public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, Func<object, HelperResult> startHtml, IDictionary<string, object> htmlAttributes) { return LabelFor(html, expression, startHtml, null, htmlAttributes); } /// <summary>Creates a Label with custom Html before and after the label text. Starting Html and ending Html are provided.</summary> /// <param name="startHtml">Html to preempt the label text.</param> /// <param name="endHtml">Html to follow the label text.</param> /// <returns>MVC Html for the Label</returns> public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml, Func<object, HelperResult> endHtml) { return LabelFor(html, expression, startHtml, endHtml, new RouteValueDictionary("new {}")); } /// <summary>Creates a Label with custom Html before and after the label text. Starting Html, ending Html, and a single Html attribute are provided.</summary> /// <param name="startHtml">Html to preempt the label text.</param> /// <param name="endHtml">Html to follow the label text.</param> /// <param name="htmlAttributes">A single Html attribute to include.</param> /// <returns>MVC Html for the Label</returns> public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, Func<object, HelperResult> startHtml, Func<object, HelperResult> endHtml, object htmlAttributes) { return LabelFor(html, expression, startHtml, endHtml, new RouteValueDictionary(htmlAttributes)); } /// <summary>Creates a Label with custom Html before and after the label text. Starting Html, ending Html, and a collection of Html attributes are provided.</summary> /// <param name="startHtml">Html to preempt the label text.</param> /// <param name="endHtml">Html to follow the label text.</param> /// <param name="htmlAttributes">A collection of Html attributes to include.</param> /// <returns>MVC Html for the Label</returns> public static MvcHtmlString LabelFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression, Func<object, HelperResult> startHtml, Func<object, HelperResult> endHtml, IDictionary<string, object> htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); string htmlFieldName = ExpressionHelper.GetExpressionText(expression); //Use the DisplayName or PropertyName for the metadata if available. Otherwise default to the htmlFieldName provided by the user. string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); if (String.IsNullOrEmpty(labelText)) { return MvcHtmlString.Empty; } //Create the new label. TagBuilder tag = new TagBuilder("label"); //Add the specified Html attributes tag.MergeAttributes(htmlAttributes); //Specify what property the label is tied to. tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); //Run through the various iterations of null starting or ending Html text. if (startHtml == null && endHtml == null) tag.InnerHtml = labelText; else if (startHtml != null && endHtml == null) tag.InnerHtml = string.Format("{0}{1}", startHtml(null).ToHtmlString(), labelText); else if (startHtml == null && endHtml != null) tag.InnerHtml = string.Format("{0}{1}", labelText, endHtml(null).ToHtmlString()); else tag.InnerHtml = string.Format("{0}{1}{2}", startHtml(null).ToHtmlString(), labelText, endHtml(null).ToHtmlString()); return MvcHtmlString.Create(tag.ToString()); } } }