2014-02-19 73 views
53

在我看來,我有一個enumdropdownlist(Asp.Net MVC 5.1中的新功能)。Html.EnumDropdownListFor:顯示默認文本

@Html.EnumDropDownListFor(m => m.SelectedLicense,new { @class="form-control"}) 

如果我執行上面的代碼,我得到我的下面的枚舉dropdownlist。

public enum LicenseTypes 
{ 
    Trial = 0, 
    Paid = 1 
} 

但默認情況下我想我的下拉列表有一個值(自定義文本) ,這就是我想

@Html.EnumDropDownListFor(m => m.SelectedLicense,"Select a license" ,new { @class="form-control"}) 

但現在的問題是,當我運行它,我的下拉列表看起來像這 enter image description here 因此,我想要顯示的默認文本默認情況下不會顯示。 如果用戶選擇「選擇許可證」並嘗試提交表單,它確實會顯示一個錯誤,指出「選擇許可證」,但它不會顯示爲默認文本。 我需要改變的東西?

Ps:圖像是加載時頁面的屏幕截圖。默認情況下,它將顯示試用爲選定選項。

+1

由邁克爾·理查森答案應該真正做到了正確的答案。 –

回答

68

試圖改變從1LicenseTypesIndex開始不0象下面這樣:

public enum LicenseTypes 
{ 
    Trial = 1, 
    Paid = 2 
} 

然後你可以使用Range attribute驗證像下面選定的許可證類型:

public class YourViewModel 
{ 
    //Other properties 
    [Range(1,int.MaxValue,ErrorMessage = "Select a correct license")] 
    public LicenseTypes LicenseTypes { get; set; } 
} 

最後,您的看法:

@Html.EnumDropDownListFor(m => m.LicenseTypes,"Select a license",new { @class = "form-control"}) 
    @Html.ValidationMessageFor(m => m.LicenseTypes) 
+0

工作,但是,然後它將添加'選擇一個許可證'作爲其中一個ID爲0的枚舉值。我希望能夠顯示錯誤消息,當用戶不從枚舉中選擇一個值。 – Cybercop

+0

可以做到這一點,但我會讓它不被接受一段時間,看看是否有人可以得到更好的解決方案,直到然後+1爲你的想法。 – Cybercop

+2

@probackpacker有更好的答案,這個選項不會被驗證處理陷入 – Dan

60

當您的EnumDropDownListFor呈現時SelectedLicense已具有該類型的默認值,即0

只要改變你的SelectedLicense屬性的類型爲可空枚舉,就像這樣:

public LicenseTypes? SelectedLicense { get; set; } 

這也讓您可以繼續使用Required屬性,我認爲這是顯著清潔。 Required屬性將不允許空響應,因此即使您的模型允許使用空值,表單也不會。

+1

我認爲這是今天的最佳答案,但看起來像一個黑客。真正的修復應該在MVC內正確處理不可空的枚舉。 – jhilden

+2

@jhilden,我認爲,MVC _is_正確地處理不可空的Enum,通過做_Exactly_你正在告訴它做的事情。在.NET [枚舉變量始終初始化爲值0](http://stackoverflow.com/a/529937/1812515)。假設您將屬性類型作爲非空值枚舉('LicenseTypes'),並且選擇了「選擇許可證」(無值列表項)的表單。您的'SelectedLicense'屬性將以默認值('Trial')結束。如果您只是檢查了模型,那麼與實際選擇「Trial」值的用戶將無法區分。 –

+0

你是對的。我回頭看看我的其他代碼,如果我們想要一個int,但沒有默認值,那麼我們這樣做: [必需的] public int? NullableIntHere {get; set;} – jhilden

13

我有一個枚舉:

public enum Sex 
{ 
    Male, 
    Female 
} 

在我的模型,我有:

[DisplayName("Sex")] 
    [Required] 
    public Sex? Sex { get; set; } 

的視圖:

@Html.EnumDropDownListFor(model => model.Sex, "Select sex", new { @class = "form-control", type = "text"}) 

通過這一點,我有默認選項下拉「選擇性別」,但驗證只接受enum(「男性」和「女性」)提供的選項。

在MVC3(無EnumDropDownListFor)我在模型中使用:

[DisplayName("Sex")] 
    [Required(AllowEmptyStrings=false)] 
    public Sex? Sex { get; set; } 

    Sex = null; 

    Sexes = Repository.GetAutoSelectList<Sex>(""); 

鑑於:

@Html.DropDownListFor(model => model.Sex, Model.Sexes, new { @class = "form-control", type = "text" }) 
6

視圖模型類需要對枚舉屬性設置的默認值它是默認選中 大衆

public class Test 
    { 
     public Cars MyCars { get; set; } 
     public enum Cars 
     { 
      [Display(Name = @"Car #1")] 
      Car1 = 1, 
      [Display(Name = @"Car #2")] 
      Car2 = 2, 
      [Display(Name = @"Car #3")] 
      Car3 = 3 
     } 

    } 

控制器:

public class EnumController : Controller 
    { 
     // GET: Enum 
     public ActionResult Index() 
     { 
      var model = new Test {MyCars = Test.Cars.Car3}; // set default value 
      return View(model); 
     } 
     [HttpPost] 
     public ActionResult Index(Test model) 
     { 
      ..... 
     } 
    } 

查看:

@Html.BeginForm() 
{ 
<div class="panel bg-white"> 
    <div class="panel-header fg-white"> 
     Enums 
    </div> 
    <div class="panel-content"> 
     <div class="input-control select size3"> 
      @Html.EnumDropDownListFor(model => model.MyCars) 

     </div> 
    </div> 
    <input type="submit" class="button success large" /> 
</div> 
} 
0

上午我有點晚了?

更改枚舉類型的值不是很令人滿意。

兩者都不是將模型屬性更改爲可以爲空,然後添加[必需的]屬性以防止它爲空。

我建議使用ViewBag來設置下拉列表的默認選定值。 控制器的第四條線是唯一重要的。

編輯:啊......新手...我的第一個想法是使用ModelState.SetModelValue,因爲我的新手的本能阻止我只是儘量設置在ViewBag所需的值,因爲下拉被綁定到模型。我肯定有一個問題:它會綁定到模型的屬性,而不是ViewBag的屬性。我全錯了:ViewBag沒問題。我更正了代碼。

這裏是一個例子。

型號:

namespace WebApplication1.Models { 

    public enum GoodMusic { 
     Metal, 
     HeavyMetal, 
     PowerMetal, 
     BlackMetal, 
     ThashMetal, 
     DeathMetal // . . . 
    } 

    public class Fan { 
     [Required(ErrorMessage = "Don't be shy!")] 
     public String Name { get; set; } 
     [Required(ErrorMessage = "There's enough good music here for you to chose!")] 
     public GoodMusic FavouriteMusic { get; set; } 
    } 
} 

控制器:

namespace WebApplication1.Controllers { 
    public class FanController : Controller { 
     public ActionResult Index() { 
      ViewBag.FavouriteMusic = string.Empty; 
      //ModelState.SetModelValue("FavouriteMusic", new ValueProviderResult(string.Empty, string.Empty, System.Globalization.CultureInfo.InvariantCulture)); 
      return View("Index"); 
     } 
     [HttpPost, ActionName("Index")] 
     public ActionResult Register(Models.Fan newFan) { 
      if(!ModelState.IsValid) 
       return View("Index"); 
      ModelState.Clear(); 
      ViewBag.Message = "OK - You may register another fan"; 
      return Index(); 
     } 
    } 
} 

查看:

@model WebApplication1.Models.Fan 
<h2>Hello, fan</h2> 
@using(Html.BeginForm()) { 
    <p>@Html.LabelFor(m => m.Name)</p> 
    <p>@Html.EditorFor(m => m.Name) @Html.ValidationMessageFor(m => m.Name)</p> 
    <p>@Html.LabelFor(m => m.FavouriteMusic)</p> 
    <p>@Html.EnumDropDownListFor(m => m.FavouriteMusic, "Chose your favorite music from here...") @Html.ValidationMessageFor(m => m.FavouriteMusic)</p> 
    <input type="submit" value="Register" /> 
    @ViewBag.Message 
} 

Without the "ModelState.SetModelValue or ViewBag.FavouriteMusic = string.Empty" line in the model Index action the default selected value would be "Metal" and not "Select your music..."

+0

@shim:它適用於從主視圖調用的局部視圖,但不適用於AJAX中調用的局部視圖。 部分視圖獲取主視圖ViewBag的副本。 您在主視圖調用分部視圖時執行索引操作。當AJAX請求調用局部視圖時您不需要。 Index.cshtml: – Rikou