I am working on an MVC project and would like to pass the property name to the Html.TextboxFor method. This is my view model.
public class RuleViewModel<T> where T : class, IValidatableObject
{
private T _rule;
public T RuleModel
{
get
{
return _rule
?? (_rule = Activator.CreateInstance<T>());
}
}
public RuleMetadata Metadata { get; set; }
public Expression<Func<RuleViewModel<T>, Object>> 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<Func<RuleViewModel<T>, Object>>(fieldExpression, fieldName);
return exp;
}
}
Then in the view I do it
@foreach (var prop in Model.RuleModel.GetType().GetProperties())
{
var result = Model.Metadata.Columns.SingleOrDefault(m => m.ColumnName == prop.Name);
if (result != null)
{
<td>
@Html.TextBoxFor(Model.GetParameterByName(prop))
</td>
}
}
The problem is that when the property is of type decimal ?, I get a, cannot convert the value with a zero number to an object error. I looked around and found that you can use Expression.Convert to fix this, but when I do this, I get an error in the view
Templates can only be used with access to a field, access to resources, an index of a one-dimensional array, or one-parameter expressions of a custom indexer.
. , , .