2010-06-13 78 views
13

對不起,如果這是一個dup,我的搜索什麼都沒有發現。從ASP.net中的枚舉中的下拉列表中選擇的項目MVC

我使用下面的方法來產生下拉的枚舉類型列表中(從這裏升起:http://addinit.com/?q=node/54):

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected) 
{ 
    if (!type.IsEnum) 
     throw new ArgumentException("Type is not an enum."); 

    if(selected != null && selected.GetType() != type) 
     throw new ArgumentException("Selected object is not " + type.ToString()); 

    var enums = new List<SelectListItem>(); 
    foreach (int value in Enum.GetValues(type)) 
    { 
     var item = new SelectListItem(); 
     item.Value = value.ToString(); 
     item.Text = Enum.GetName(type, value); 

     if(selected != null) 
      item.Selected = (int)selected == value; 

     enums.Add(item); 
    } 

    return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, enums, "--Select--"); 
} 

它工作正常,除了一兩件事。如果我給出的下拉列表與我的模型上的屬性名稱相同,則選擇的值設置不正確。含義這個工程:

<%= Html.DropDownList("fam", typeof(EnumFamily), Model.Family)%> 

但這並不:

<%= Html.DropDownList("family", typeof(EnumFamily), Model.Family)%> 

因爲我想直接傳遞整個對象到控制器方法我張貼到,我會真的喜歡爲模型上的屬性命名下拉列表。當使用「正確」的名稱,下拉列表確實發佈,我似乎無法設置選定的值。

我不認爲這個問題,但我在Mono運行MVC 1 2.6

編輯:我剛剛測試在Windows操作系統上,而我看到了同樣的行爲

+0

我看到了相同的行爲,並通過使用不同的命名下拉列表來解決。 – Nate 2010-06-18 14:59:33

回答

14

儘量不要使用int值對的枚舉/改爲:

item.Value = value.ToString();

使用:

item.Value = Enum.GetName(type, value);

IMO發生的事情是它會自動將選定的下拉列表值設置爲與模型匹配 - 使用枚舉名稱而不是其int值。請記住,視圖引擎不僅在發佈的表單中(在已發佈的情況下)查找已選定的值,而且還在將model + viewdata傳遞給視圖的情況下查找已選定的值。只有在它沒有找到它的情況下,它纔會使用您指定的選定值。

+0

這似乎只是弗雷迪的門票 - 非常感謝。我希望我能讓這個獎金更高。我真的認爲它會通過枚舉值來綁定,但它最終會知道發生了什麼。現在我必須回去並撤消所有的黑客,所以我想我應該對你生氣;) – AlexCuse 2010-06-18 20:44:13

0

這不似乎很正確,但我發現如果使用{nameOfInputParameter}。{propertyName}命名下拉列表,它會正確加載AND文章。所以,如果有問題的形式張貼到一個方法,採取所謂的「基於myModel」類型相同形式的模型家庭下拉可以設立這樣的參數:

<%= Html.DropDownList("myModel.family", typeof(EnumFamily), Model.Family)%> 

這使得用一個id myModel_family的名稱和myModel.family的名稱。我不知道該如何去感受,這對我來說似乎有點不合適。但它似乎到目前爲止工作。但它引入了一個新問題。你可以不再初始化文本框等......像這樣:

<%= Html.TextBox("name") %> 

這將正確加載的值,但是當你郵寄到控制器的方法以「基於myModel」的值不被識別爲一個參數部分被提交的對象。所以我們需要在參數名稱中包含參數名稱。

但是,以下不能解決的值,至少使用默認的模型粘合劑(我想知道如果周圍挖在那裏將舉辦最好的回答這個問題):

<%= Html.TextBox("myModel.name") %> 

所以,你需要這樣做:

<%= Html.TextBox("myModel.name", Model.Name) %> 

這一切變得相當總值(尤其是在那裏我需要能夠應對在模型是空的情況下頁)。希望別人有更好的想法:)

4

實際上,這是解決方案。這個問題與我的解決方案相同。
ASP.NET MVC - Html.DropDownList - Value not set via ViewData.Model

public static string DropDownList(this HtmlHelper helper, string name, Type type, object selected) 
    { 
     if (!type.IsEnum) 
      throw new ArgumentException("Type is not an enum."); 

     if (selected != null && selected.GetType() != type) 
      throw new ArgumentException("Selected object is not " + type.ToString()); 

     var enums = new List<SelectListItem>(); 
     foreach (int value in Enum.GetValues(type)) 
     { 
      var item = new SelectListItem(); 
      item.Value = value.ToString(); 
      item.Text = Enum.GetName(type, value); 

      if (selected != null) 
       item.Selected = (int)selected == value; 

      enums.Add(item); 
     } 

     // set ViewData first 
     helper.ViewData[name] = enums; 

     // pass in "null" intentionally into the DropDownList extension method 
     return System.Web.Mvc.Html.SelectExtensions.DropDownList(helper, name, null, "--Select--"); 
    } 

使用item.Value = Enum.GetName(type, value);使得下拉<選項>值呈現爲枚舉名稱。 我個人比較喜歡int值作爲回傳。

希望它有幫助。

+0

有趣的 - 我沒有想到使用ViewData那樣。我不確定在這一點上我想要走這條路線,但我真的很感謝答覆。如果我遇到目前的方法存在任何問題,我將確保嘗試一下。 – AlexCuse 2010-06-19 02:19:15

+0

這是一個很棒的答案,謝謝! – loraderon 2010-07-20 17:23:46

+0

這真是太棒了,我一直在尋找解決方案 – bman 2013-08-03 06:50:33

相關問題