2014-06-20 76 views
0

我想要做的是創建一個html擴展方法,以在mvc項目中構建一組單選按鈕。我知道我可以寫一個for循環,但這是一個非常有用的方法在其他項目中重用,所以我想弄清楚這一點。將屬性表達式傳遞給從對象中選擇值的方法

我想要做的是能夠傳遞單選按鈕的模型屬性的表達式(所以我可以命名單選按鈕相同的東西並選擇選定的選項),這是一個對象集合選項和選項對象的屬性用作單選按鈕的值。

這是我到目前爲止,但它不起作用。 (我得到錯誤「無法將方法組''值'轉換爲非委託類型'字符串'。是否打算調用該方法?」)。

public static HtmlString RadioOptionsFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> modelExpression, 
     IEnumerable<object> radioOptions, 
     Expression<Func<object, string>> valueExpression) 
    { 
     StringBuilder sb = new StringBuilder(); 
     var propertyName = ((MemberExpression)(modelExpression.Body)).Member.Name; 

     radioOptions.Select(el => sb.Append(htmlHelper.RadioButton(propertyName, valueExpression.Compile()(el)))); 

     return new HtmlString(sb.ToString()); 
    } 


@Html.RadioOptionsFor(x => x.Category, Model.CategoryOptions, e => e.Value) 

UPDATE: 好了,所以StriplingWarrior幫我得到一個有效的解決方案。問題是將第二個表達式函數的參數聲明爲對象。它應該是一個泛型類型,所以我只需要改變它的方法聲明。我還添加了一個幫助器方法來構建一個帶有包裝標籤元素的單選按鈕。我也做了一些linq串聯,所以我不必循環兩次。最後,我添加了選擇模型的當前值並刪除單選按鈕元素的重複ID。這是最終的解決方案。

public static string RadioButtonWithLabel<TModel>(this HtmlHelper<TModel> htmlHelper, string name, string value, string selectedValue) 
    { 
     var sb = new StringBuilder(); 
     sb.Append("<label for=\"").Append(name).AppendLine("\">") 
      .AppendLine(htmlHelper.RadioButton(name, value, selectedValue.Equals(value), new { id = "" }).ToString()) 
      .Append(value).AppendLine("</label>"); 

     return sb.ToString(); 
    } 

    public static HtmlString RadioOptionsFor<TModel, TProperty, TElement>(this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> modelExpression, 
     string selectedValue, 
     IEnumerable<TElement> radioOptions, 
     Expression<Func<TElement, string>> valueExpression) 
    { 
     var propertyName = ((MemberExpression)(modelExpression.Body)).Member.Name; 

     var result = radioOptions.Aggregate(new StringBuilder(), (sb, el) => sb.Append(htmlHelper.RadioButtonWithLabel(propertyName, valueExpression.Compile()(el), selectedValue))); 

     return new HtmlString(result.ToString()); 
    } 

這樣調用

@Html.RadioOptionsFor(x => x.Category, Model.Category, Model.CategoryOptions, e => e.Value) 

回答

0

Expression<Func<object, string>> valueExpression期待你的表達,產生的字符串:什麼是e.Value類型?

好像e.Value不應該存在,因爲e是一個對象。這是一種擴展方法嗎?如果是這樣,你可能需要通過:

e => e.Value() 

所以,破譯你的錯誤信息:它不能「值」(這是一種方法或代表)轉換至由表達式預期string:你打算調用產生一個字符串的方法?

+0

e.Value應該是集合中要用作單選按鈕值的元素的屬性。 所以在我的例子中,我傳遞了一個XElement集合,我想使用XElement對象的Value屬性作爲單選按鈕的值 我打算最終添加一個檢查來驗證該屬性是否屬於類型字符串 – Alex

+0

@Alex:你寫上面代碼的方式,'e'被轉換爲'object',所以它沒有'Value'屬性。也許這應該是一個泛型類型呢? – StriplingWarrior