设想
public class Element {
public int Id {get;set;}
}
public class ViewModel {
public IList<Element> Elements{get;set;}
}
我有一个带有 type 参数的方法Expression<Func<Element, int>>
,看起来像m => m.Id
我想变身
m => m.Id
(其中 m 是一个元素)
至
x => x.Elements[0].Id
其中 x 是 ViewModel,0 是“索引”参数
我现在拥有的(当然是通用的,为了清楚起见,我删除了通用部分)
public static class Helpers {
public static Expression<Func<ViewModel, int>> BuildExpressionArrayFromExpression(
this Expression<Func<Element, int>> expression,
ViewModel model,
int index = 0,
string bindingPropertyName = "Elements"//the name of the "List" property in ViewModel class
)
{
var parameter = Expression.Parameter(typeof(ViewModel), "x");
var viewModelProperty = model.GetType().GetProperty(bindingPropertyName);
Expression member = parameter;//x => x
member = Expression.Property(member, viewModelProperty);//x => x.Elements
var test1 = Expression.Property(member, "Item", new Expression[]{Expression.Constant(index)});
//x => x.Elements.Item[0], and I don't want Item
var test2 = Expression.Call(member, viewModelProperty.PropertyType.GetMethod("get_Item"), new Expression[] {Expression.Constant(index)});
//x 0> x.Elements.get_Item(0), and I don't want get_Item(0)
//code to add Id property to expression, not problematic
return Expression.Lambda<Func<ViewModel, int>(member, parameter);
}
}
编辑
我需要x => x.Elements[0]
而不是x => x.Elements.Item[0]
,因为结果表达式必须用InputExtensions.TextBoxFor(<myIndexedExpression>)
想象一下这样的班级
public class Test {
public int Id {get;set;}
public IList<Element> Elements {get;set;}
}
和一个后期动作
[HttpPost]
public ActionResult Edit(Test model) {
bla bla bla.
}
如果我的输入的名称属性没有很好地生成,那么我就会遇到绑定问题(model.Elements 在我的 Post Action 中是空的)。
我输入的名称属性应该是
Elements[0]PropertyName
我得到(取决于我的尝试)
PropertyName
或(也许不准确,我尝试重现这种情况)
Elements.Item[0].PropertyName
编辑2
还尝试了一个不同的解决方案,使用 ViewData.TemplateInfo.HtmlFieldPrefix,但我得到了
Elements.[0].PropertyName
(和 Elements_ 0 _PropertyName 作为 Id)。
第一个点在名称中是不需要的,第一个“双下划线”应该是 id 中的简单点。
我实际上使用这个解决方案,使用正则表达式(argh)来删除不需要的。和 _ ,但我想避免这种情况。