2014-02-12 18 views
3

我正在開發一個MVC項目,並希望將Html.TextboxFor方法傳遞給一個屬性的名稱。這是我的視圖模型成員表達式無法將對象轉換爲可空的十進制

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; 
    } 

} 

然後在視圖中我做這

@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> 
     } 
    } 

的問題是,當屬性的類型爲十進制的?我得到一個不能轉換爲空的小數對象錯誤。我環顧四周,發現可以使用Expression.Convert來解決這個問題,但是當我這樣做時,我在視圖上出現錯誤

模板只能用於字段訪問,屬性訪問,單維數組索引或單參數自定義索引器表達式。

任何幫助,將不勝感激。這是我正在研究的一個概念驗證項目,如果沒有這件作品,它會死在水中。

回答

2

問題是,您不能僅在調用TextBoxFor<TModel, TProperty>()時使用object作爲TProperty。它期望形式爲Func<TModel, TProperty>的lambda表達式,並且C#的方差規則是這樣的,即Func<TModel, decimal?>不與Func<TModel, object>分配兼容。你也不能簡單地使用Convert(),因爲MVC內部不會接受一個lambda,它的正文是Convert表達式。

可以做的是使用什麼樣的動態綁定來調用TextBoxFor<TModel, TProperty>()正確類型的參數:

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)) 
+0

感謝您的幫助。當我這樣做時,我得到一個運行時錯誤,說沒有可用的方法名爲'TextBoxFor',但似乎有一個名稱的擴展方法。擴展方法不能動態分派。有任何想法嗎?通過定義四個或五個不同的GetParameter方法,每個方法都使用不同的返回類型,並在視圖中使用條件語句,這些條件語句可用於概念驗證,但我認爲這很難看。 – jfin3204

+0

如果你靜態調用TextBoxFor()會怎麼樣?看看這是否工作:'@ InputExtensions.TextBoxFor(Html,(dynamic)Model.GetParameterByName(prop))' –

+0

標記你是一個美麗的男人。那就是訣竅。非常感謝。 – jfin3204

相關問題