The following is working, but my Body.NodeType changes to Convert, instead of MemberAccess which is a problem when getting 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;
}
In the context of a ASP.NET MVC 2.0, I have my own EditorFor:
public MvcHtmlString EditorFor<TProperty>(Expression<Func<TModel, TProperty>> expression)
The EditorFor then delegates the call internally, based on metadata, to specific methods, ex:
public DecimalTextBox DecimalTextBoxFor(Expression<Func<TModel, decimal?>> expression)
The DecimalTextBox has a Value property of type decimal?, so I want to set it:
decimalTextBox.Value(expression.Compile()(ViewData.Model));
Call form the EditorFor to the DecimalTextboxFor doesn't compile bacause the types don't match, and that's why I need the conversion.
Above code, does the conversion, but because the Expression.Body.NodeType is changed, the ModelMetadata.FromLambdaExpression doesn't work, because the expression type needs to be an ArrayIndex, Call, MemberAccess or Parameter. Convert is not accepted.
My workaround is changing the DecimalTextBoxFor into:
public DecimalTextBox DecimalTextBoxFor(Expression<Func<TModel, TProperty>> expression)
and convert the value inside there:
decimalTextBox.Value((decimal?) Convert.ChangeType(expression.Compile()(ViewData.Model), typeof(decimal?)));
An other conversion that does partially work is:
private Expression<Func<TModel, TNewProperty>> ConvertExpression<TProperty, TNewProperty>(Expression<Func<TModel, TProperty>> expression)
{
Expression<Func<TModel, TNewProperty>> convertedExpression = expression as Expression<Func<TModel, TNewProperty>>;
}
But converting different value types (ex. single to double) doesn't work of course.
I was hoping to convert the Expression itself...