将EditorTemplate转换为HtmlHelper

时间:2012-02-08 17:48:35

标签: c# asp.net-mvc

我最初创建了一个像这样的编辑器模板

@model MyModel
var items = // get items
@Html.DropDownListFor(m => m.Id, items, new { id = Html.IdFor(m => m) })

调用
@Html.EditorFor(m => m.SomeClass)

其中SomeClass具有Id属性。 (IdFor是我的HTML助手之一。)

这会产生类似这样的东西

<select name="SomeClass.Id" id="SomeClass" />

现在我想将编辑器模板更改为HTML帮助器,以便我的调用看起来像这样

@Html.CustomEditorFor(m => m.SomeClass)

我正在将其从视图更改为帮助程序,因为它更容易重用。

这就是我所拥有的:

public static MvcHtmlString CustomEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
    var idString = htmlHelper.IdFor(expression);
    var propertyValue = expression.Compile()(htmlHelper.ViewData.Model);
    var items = // get items
    return htmlHelper.DropDownListFor(expression, items, new {id = idString});
}

但是,当我调用编辑器时,我会得到这个HTML而不是我想要的。

<select name="SomeClass" id="SomeClass" />

如何修改表达式以允许它“访问”Id属性?

1 个答案:

答案 0 :(得分:1)

试试这个:

public static MvcHtmlString CustomEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
    var idString = htmlHelper.IdFor(expression);
    var items = // get items

    var param = Expression.Parameter(typeof(TModel), "m");
    var member = Expression.Property(
                     Expression.Property(param, ExpressionHelper.GetExpressionText(expression))
                 , "Id");

    var isNullable = Nullable.GetUnderlyingType(member.Type);
    if (isNullable != null) {
        var expr2 = Expression.Lambda<Func<TModel, int?>>(
                        member, new[] { param }
                    );

        return htmlHelper.DropDownListFor(expr2, items, new { id = idString });
    }

    var expr = Expression.Lambda<Func<TModel, int>>(
                   member, new[] { param }
               );

    return htmlHelper.DropDownListFor(expr, items, new { id = idString });
}