シナリオ
public class Element {
public int Id {get;set;}
}
public class ViewModel {
public IList<Element> Elements{get;set;}
}
タイプのパラメータを持つメソッドがあります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.
}
入力の名前属性が適切に生成されていない場合は、バインディングの問題が発生します(モデル。要素はポストアクションで空です)。
入力の名前属性は次のようになります
Elements[0]PropertyName
そして私は(私の試みに応じて)得る
PropertyName
または(正確ではないかもしれませんが、私はこのケースを再現しようとしています)
Elements.Item[0].PropertyName
EDIT2
また、ViewData.TemplateInfo.HtmlFieldPrefixを使用して別の解決策を試しましたが、その後、
Elements.[0].PropertyName
(およびElements_ 0 _PropertyName as Id)。
最初のドットは名前では不要であり、最初の「二重アンダースコア」はidの単純なものである必要があります。
私は実際にこのソリューションを使用し、正規表現(argh)を使用して不要なものを削除します。と_、しかし私はこれを避けたいです。