2012-01-05 19 views
4

我想創建一個需要2個下拉列表與MVC 3的視圖。在我唯一的其他MVC應用程序中,我們使用了使用Ajax方法填充數據的Telerik控件。現在在這個項目中,我們不使用第三方控件,所以我將使用MVC SelectList作爲下拉菜單。我一直在閱讀大量關於如何填充SelectList的文章,但他們都沒有兩次說過同樣的事情,總是用不同的方式來創建模型,有些使用ViewData或來保存集合並傳遞到視圖等沒有一致性。MVC在回發中選擇與模型列表,如何?

在MVC視圖中使用模型本身作爲數據填充下拉的最佳方法是什麼,而不是ViewData。當用戶從列表中進行選擇時,提交併調用HttpPost操作,如何從選擇列表屬性的Model屬性訪問選定的值?

這是我目前型號:

public class TemporaryRegistration { 
    [Required] 
    [Email(ErrorMessage = "Please enter a valid email address.")] 
    [Display(Name = "Email address")] 
    public string Email { get; set; } 

    [Required] 
    [Integer] 
    [Min(1, ErrorMessage = "Please select an entity type.")] 
    [Display(Name = "Entity Type")] 
    public IEnumerable<SelectListItem> EntityType { get; set; } 

    [Required] 
    [Integer] 
    [Min(1, ErrorMessage = "Please select an associated entity.")] 
    [Display(Name = "Associated Entity")] 
    public IEnumerable<SelectListItem> AssociatedEntity { get; set; } 
} 

這是我目前看來,它僅使用TextBoxFor,我需要使用下拉菜單,我怎麼把它們變成下拉菜單?

@model Web.Models.TemporaryRegistration 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@using (Html.BeginForm()) { 
    @Html.ValidationSummary(true) 
    <fieldset> 
    <legend>Create New ELM Select User</legend> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Email) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Email) 
      @Html.ValidationMessageFor(model => model.Email) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.EntityType) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.EntityType) 
      @Html.ValidationMessageFor(model => model.EntityType) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.AssociatedEntity) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.AssociatedEntity) 
      @Html.ValidationMessageFor(model => model.AssociatedEntity) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

這是我當前的發帖操作: 如何獲取選定的值?

[HttpPost] 
public ActionResult CreateUser(TemporaryRegistration registrationModel) { 
    string newRegistrationGUID = string.Empty; 
    if (!ModelState.IsValid) { 
     return View(); 
    } 

    TemporaryRegistrationEntity temporaryRegistration = null; 
    temporaryRegistration = new TemporaryRegistrationEntity(registrationModel.Email, registrationModel.EntityType, registrationModel.AssociatedEntity); 
    newRegistrationGUID = temporaryRegistration.Save(); 
    return Content("New registration was created with GUID " + newRegistrationGUID); 
} 

回答

8

從評論...繼續

比方說,你有一個名爲Toy模型。玩具具有屬性,如NamePrice,並Category

public class Toy() 
{ 
    public string Name; 
    public double Price; 
    public string Category 
} 

現在你想建立一個表單視圖添加Toy,人們需要能夠從下降的可能性降低選擇一個類別...但您不想通過ViewDataViewBag出於某種原因這樣做。

不是傳遞模型到視圖,創建一個ToyViewModelNamePriceCategory ...但有一個類的集合來填充下拉:

public class ToyViewModel() 
{ 
    public string Name; 
    public double Price; 
    public string Category 

    public ICollection<string> Categories; 
} 

現在你控制器做到這一點:

public ActionResult GetToyForm() 
{ 
    var viewModel = new ToyViewModel(); 
    viewModel.Categories = _service.GetListOfCategories(); 
    return View(viewModel); 
} 

你的看法被綁定到視圖模型,並使用model.Categories集合來填充你的下拉菜單。它應該是這個樣子:

@Html.DropDownListFor(model => model.Category, model.Categories) 

當您提交它,你的控制器確實是這樣的:

[HttpPost] 
public ActionResult CreateToy(ToyViewModel _viewModel) 
{ 
    var model = new Toy(); 
    model.Name = _viewModel.Name 
    // etc. 

    _service.CreateToy(model); 

    // return whatever you like. 
    return View(); 
} 

這是很好的做法,使的ViewModels結合視圖,以便您可以將它們調整到需要您的表示層,同時讓您的模型保持接近數據層和業務邏輯。

+0

感謝您的澄清,這正是我使用的架構類型。要求實際上讓我使用3種不同的模型:ViewModel,一種業務實體模型,它是在後期從ViewModel轉換而來的,DTO是用於輕量級網絡流量。 – 2012-01-06 14:22:01

+1

@ one.beat.consumer我沒有看到這與原始文章有什麼不同。原始文章中的視圖模型是「TemporaryRegistration」,實體/持久性模型是「TemporaryRegistrationEntity」。在這個答案的唯一區別就是你的遺漏了元數據,並使用**完全相同的模式,包括我曾經使用的類別,這就是問題所在...... – 2012-01-06 14:39:52

+0

謝謝,兩者都是你們在一起幫助我看到了整個畫面,看起來我正以正確的方式進行。 TemporaryRegistrationEnitity確實是我的商業模式,而TemporaryRegistration只是視圖模型。爲了清晰起見,我將它重命名爲TemporaryRegistrationViewModel。 – 2012-01-06 14:45:32

2

EntityType並不需要是一個列表,除非你接受多個值回(如列表框將發送)。當您在視圖中顯示下拉列表(通常只選擇一個值)時,您只需以其他方式爲其提供選擇,例如在視圖模型的另一個屬性中發送列表。

public class TemporaryRegistration { 
     [Required] 
     [Email(ErrorMessage = "Please enter a valid email address.")] 
     [Display(Name = "Email address")] 
     public string Email { get; set; } 

     [Required] 
     [Integer] 
     [Min(1, ErrorMessage = "Please select an entity type.")] 
     [Display(Name = "Entity Type")] 
     public int EntityType { get; set; } 

     public IEnumerable<SelectListItem> EntityTypes { get; set; } 

     [Required] 
     [Integer] 
     [Min(1, ErrorMessage = "Please select an associated entity.")] 
     [Display(Name = "Associated Entity")] 
     public IEnumerable<SelectListItem> AssociatedEntity { get; set; } 
} 

然後使用下拉列表助手。

@Html.DropDownListFor(model => model.EntityType, model.EntityTypes) 
+2

好的,所以當我回發時,我假設你的意思是模型中的EntityType將被設置爲EntityTypes的選定值?並且,在控制器的Get方法操作中,我假設我只需要實例化一個新的viewmodel,獲取一個EntityTypes集合並將它們設置爲myModel.EntityTypes的值,以便它們傳入視圖? – 2012-01-05 19:20:43

+0

@CDSmith是的,這是正確的。 – 2012-01-05 19:22:21

+0

好的真棒,謝謝! – 2012-01-05 19:23:29

相關問題