The problem is that you can't just use object
as TProperty
when calling TextBoxFor<TModel, TProperty>()
. It expects a lambda expression of the form Func<TModel, TProperty>
, and the variance rules of C# are such that a Func<TModel, decimal?>
is not assignment compatible with Func<TModel, object>
. You also can't simply use Convert()
, because the MVC internals won't accept a lambda whose body is a Convert
expression.
What you can do is use dynamic binding to invoke TextBoxFor<TModel, TProperty>()
with the correct type arguments:
public Expression GetParameterByName(PropertyInfo pi)
{
var fieldName = Expression.Parameter(typeof(RuleViewModel<T>), "x");
var fieldExpression = Expression.PropertyOrField(
Expression.Property(fieldName, "RuleModel"),
pi.Name);
var exp = Expression.Lambda(
typeof(Func<,>).MakeGenericType(typeof(RuleViewModel<T>), fieldExpression.Type),
fieldExpression,
fieldName);
return exp;
}
// ...
@InputExtensions.TextBoxFor(Html, (dynamic)Model.GetParameterByName(prop))