C# 将EditorTemplate转换为HtmlHelper

C# 将EditorTemplate转换为HtmlHelper,c#,asp.net-mvc,C#,Asp.net Mvc,我最初创建了这样一个编辑器模板 @model MyModel var items = // get items @Html.DropDownListFor(m => m.Id, items, new { id = Html.IdFor(m => m) }) <select name="SomeClass.Id" id="SomeClass" /> @Html.CustomEditorFor(m => m.SomeClass) 由 @Html.EditorFor

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

@model MyModel
var items = // get items
@Html.DropDownListFor(m => m.Id, items, new { id = Html.IdFor(m => m) })
<select name="SomeClass.Id" id="SomeClass" />
@Html.CustomEditorFor(m => m.SomeClass)

@Html.EditorFor(m => m.SomeClass)
其中
SomeClass
具有
Id
属性。(IdFor是我的HTML助手之一)

这会产生类似这样的结果

@model MyModel
var items = // get items
@Html.DropDownListFor(m => m.Id, items, new { id = Html.IdFor(m => m) })
<select name="SomeClass.Id" id="SomeClass" />
@Html.CustomEditorFor(m => m.SomeClass)
我将它从一个视图更改为helper,因为它更易于重用

这就是我所拥有的:

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});
}
public static MvcHtmlString CustomEditorFor(此HtmlHelper HtmlHelper,表达式)
{
var idString=htmlHelper.IdFor(表达式);
var propertyValue=expression.Compile()(htmlHelper.ViewData.Model);
var items=//获取项目
返回htmlHelper.DropDownListFor(表达式,项,新{id=idString});
}
然而,当我调用编辑器时,我得到的是这个HTML而不是我想要的

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

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

尝试以下操作:

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 });
}
public static MvcHtmlString CustomEditorFor(此HtmlHelper HtmlHelper,表达式)
{
var idString=htmlHelper.IdFor(表达式);
var items=//获取项目
var param=表达式参数(typeof(TModel),“m”);
var member=Expression.Property(
属性(参数,ExpressionHelper.GetExpressionText(表达式))
“Id”);
var isNullable=Nullable.GetUnderlyingType(member.Type);
如果(isNullable!=null){
var expr2=Expression.Lambda(
成员,新[]{param}
);
返回htmlHelper.DropDownListFor(expr2,items,new{id=idString});
}
var expr=Expression.Lambda(
成员,新[]{param}
);
返回htmlHelper.DropDownListFor(expr,items,new{id=idString});
}

是否是
new[]{Expression.Parameter(typeof(TModel),“m”)}
取决于我之前传递的内容?它可能并不总是
m
。我确实将
t属性
约束到一个接口,这样它就拥有了它。当Id属性可以是
int
int?
时,我应该做些什么?当我使用int?`时,我得到“类型'System.Int32'的表达式不能用于返回类型'System.Nullable
1[System.Int32]”。请查看修改后的代码是否有效。。再简单不过了。