Rap*_*aus 1 c# asp.net-mvc lambda expression-trees
脚本
public class Element {
public int Id {get;set;}
}
public class ViewModel {
public IList<Element> Elements{get;set;}
}
Run Code Online (Sandbox Code Playgroud)
我有一个类型参数的方法Expression<Func<Element, int>>,看起来像m => m.Id
我想改造
m => m.Id (其中m是元素)
至
x => x.Elements[0].Id 其中x是ViewModel,0是"index"参数
我现在拥有的(当然是通用的,为了清晰起见我删除了通用部分)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
我需要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;}
}
Run Code Online (Sandbox Code Playgroud)
和一个邮政行动
[HttpPost]
public ActionResult Edit(Test model) {
bla bla bla.
}
Run Code Online (Sandbox Code Playgroud)
如果我的输入的名称属性没有很好地生成,那么我有绑定问题(我的Post Action中的model.Elements为空).
我的输入的名称属性应该是
Elements[0]PropertyName
Run Code Online (Sandbox Code Playgroud)
我得到(取决于我的尝试)
PropertyName
或者(也许不确切,我试图重现这个案例)
Elements.Item[0].PropertyName
Run Code Online (Sandbox Code Playgroud)
EDIT2
还尝试了一个不同的解决方案,使用ViewData.TemplateInfo.HtmlFieldPrefix,但我得到了
Elements.[0].PropertyName
Run Code Online (Sandbox Code Playgroud)
(和Elements_ 0 _PropertyName为Id).
第一个点在名称中是不需要的,第一个"双下划线"应该是id中的简单点.
我实际上使用这个解决方案,使用正则表达式(argh)来删除不需要的东西.和_,但我想避免这种情况.
这只是表达式树的字符串表示问题,您无法更改它.你正在构建的表达式树很好.如果使用lambda表达式构建表达式树,则可以看到相同的效果:
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
class Test
{
public static void Main()
{
Expression<Func<List<string>, string>> expression = list => list[0];
Console.WriteLine(expression);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
list => list.get_Item(0)
Run Code Online (Sandbox Code Playgroud)
如果调用ToString()表达式树的结果确实是你面临的问题,我会感到非常惊讶.而不是告诉我们你认为你需要的结果和模糊的"我需要它以获得MVC绑定理由"的理由,你应该解释实际上出了什么问题.我强烈怀疑问题不在你想象的地方.
| 归档时间: |
|
| 查看次数: |
1538 次 |
| 最近记录: |