我想创建一个可以像
一样使用的帮助器@Html.MyHelperFor(m => m.Name)
这应该返回例如
<span name="Name" data-something="Name"></span>
如果是@Html.MyHelperFor(m => m.MailID)
这应该返回
<span name="MailID" data-something="MailID"></span>
我认为我应该能够在helper方法中访问Property名称以生成这种类型的帮助程序。
我该怎么做?
答案 0 :(得分:21)
您可以执行类似操作(以下内容也会采用其他HTML属性)。
public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> 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());
}
答案 1 :(得分:5)
您可以使用FromLambaExpression
中的ModelMetadata
方法,如下所示:
namespace System.Web.Mvc.Html
{
public static class CustomHelpers
{
public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> 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
方法是内置帮助程序使用的方法,因此您可以确保您的帮助程序与内置帮助程序的功能相同。通过将CustomHelpers
类放在System.Web.Mvc.Html
命名空间内,您可以像访问其他帮助者一样访问您的帮助程序,即@Html.MyHelperFor()
。
答案 2 :(得分:2)
这应该让你开始。此函数直接返回属性名称,但您应该能够通过一些工作将其转换为您正在寻找的扩展名。此示例具有正确的方法签名和对ExpressionHelper的调用以获取属性的名称。
public static MvcHtmlString MyHelperFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression)
{
string expressionName = ExpressionHelper.GetExpressionText(expression);
return new MvcHtmlString(expressionName);
}
答案 3 :(得分:1)
关注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<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> 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());
}