创建自定义Html Helper:MyHelperFor

我想创建一个可以像使用一样的帮助器

@Html.MyHelperFor(m => m.Name) 

这应该返回例如

如果它是@Html.MyHelperFor(m => m.MailID)这应该返回

我想,我应该能够在helper方法中访问Property名称来生成这种类型的帮助器。

我怎样才能做到这一点?

你可以做类似的事情(以下将采用其他HTML属性)。

 public static MvcHtmlString MyHelperFor(this HtmlHelper helper, Expression> expression, object htmlAttributes = null) { var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); string propertyName = data.PropertyName; TagBuilder span = new TagBuilder("span"); span.Attributes.Add("name", propertyName); span.Attributes.Add("data-something", "something"); if (htmlAttributes != null) { var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); span.MergeAttributes(attributes); } return new MvcHtmlString(span.ToString()); } 

您可以使用FromLambaExpression方法,如下所示:

 namespace System.Web.Mvc.Html { public static class CustomHelpers { public static MvcHtmlString MyHelperFor(this HtmlHelper helper, Expression> expression) { var metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); var name = metaData.PropertyName; // create your html string, you could defer to DisplayFor to render a span or // use the TagBuilder class to create a span and add your attributes to it string html = ""; return new MvcHtmlString(html); } } } 

ModelMetadata类位于System.Web.Mvc命名空间中。 FromLambdaExpression方法是内置帮助程序使用的方法,因此您可以确保您的帮助程序的function与内置帮助程序相同。 通过将CustomHelpers类放在System.Web.Mvc.Html命名空间中,您可以像访问其他帮助程序一样访问您的帮助程序,即@Html.MyHelperFor()

这应该让你开始。 此函数直接返回属性名称,但您应该能够通过一些工作将其转换为您正在寻找的扩展名。 此示例具有正确的方法签名和对ExpressionHelper的调用以获取属性的名称。

  public static MvcHtmlString MyHelperFor(this HtmlHelper htmlHelper, Expression> expression) { string expressionName = ExpressionHelper.GetExpressionText(expression); return new MvcHtmlString(expressionName); } 

按照mattytommo的回答,这很好用,但是当与复杂对象一起使用时只有一个小问题,例如,如果您将此代码用于EditorTemplate中的属性。

代替

 var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData); string propertyName = data.PropertyName; 

如果使用MVC4,您可以将其更改为

 var propertyName = helper.NameFor(expression); 

或MVC3及以下版本

 var propertyName = expression.Body.ToString(); propertyName = propertyName.Substring(propertyName.IndexOf(".") + 1); if (!string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix)) propertyName = string.Format("{0}.{1}", helper.ViewData.TemplateInfo.HtmlFieldPrefix, propertyName); 

完整代码:

  public static MvcHtmlString MyHelperFor(this HtmlHelper helper, Expression> expression, object htmlAttributes = null) { var propertyName = expression.Body.ToString(); propertyName = propertyName.Substring(propertyName.IndexOf(".") + 1); if (!string.IsNullOrEmpty(helper.ViewData.TemplateInfo.HtmlFieldPrefix)) propertyName = string.Format("{0}.{1}", helper.ViewData.TemplateInfo.HtmlFieldPrefix, propertyName); TagBuilder span = new TagBuilder("span"); span.Attributes.Add("name", propertyName); span.Attributes.Add("data-something", propertyName); if (htmlAttributes != null) { var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); span.MergeAttributes(attributes); } return new MvcHtmlString(span.ToString()); }