以下工作正常,但我的 Body.NodeType 更改为转换,而不是 MemberAccess ,这在获取ModelMetadata.FromLambdaExpression时出现问题:
private Expression<Func<TModel, TNewProperty>> ConvertExpression<TProperty, TNewProperty>(Expression<Func<TModel, TProperty>> expression)
{
Exression converted = Expression.Convert(expression.Body, typeof(TNewProperty));
var result = Expression.Lambda<Func<TModel, TNewProperty>>(converted, expression.Parameters);
return result;
}
在ASP.NET MVC 2.0的上下文中,我有自己的EditorFor:
public MvcHtmlString EditorFor<TProperty>(Expression<Func<TModel, TProperty>> expression)
然后,EditorFor会根据元数据在内部将调用委托给特定方法,例如:
public DecimalTextBox DecimalTextBoxFor(Expression<Func<TModel, decimal?>> expression)
DecimalTextBox有一个decimal属性的Value属性,所以我想设置它:
decimalTextBox.Value(expression.Compile()(ViewData.Model));
调用形式编辑器到DecimalTextboxFor不编译因为类型不匹配,这就是我需要转换的原因。
上面的代码,是否进行了转换,但由于Expression.Body.NodeType已更改,因此 ModelMetadata.FromLambdaExpression不起作用,因为表达式类型需要是ArrayIndex,Call,MemberAccess或Parameter。不接受转换。
我的解决方法是将DecimalTextBoxFor更改为:
public DecimalTextBox DecimalTextBoxFor(Expression<Func<TModel, TProperty>> expression)
并转换其中的值:
decimalTextBox.Value((decimal?) Convert.ChangeType(expression.Compile()(ViewData.Model), typeof(decimal?)));
其他部分有效的转换是:
private Expression<Func<TModel, TNewProperty>> ConvertExpression<TProperty, TNewProperty>(Expression<Func<TModel, TProperty>> expression)
{
Expression<Func<TModel, TNewProperty>> convertedExpression = expression as Expression<Func<TModel, TNewProperty>>;
}
但转换不同的值类型(例如单一到双)当然不起作用。
我希望转换表达本身......
答案 0 :(得分:1)
不幸的是,如果不更改NodeType
的{{1}},则无法做到这一点。 Body
表达式是一个单独的表达式类型,表示实际操作。为了实现您想要实现的目标,该操作必须是“第一”操作,即表达式树中最顶层的节点。
如果您解释为什么您认为需要Convert
保持不变,我可以提供解决方法。在语义上这没有意义:旧表达式的NodeType
表示特定操作,而您的新Body
表示不同的操作(即,原始操作后跟Body
)。您不能指望它代表旧操作,而是返回新操作的结果。