2010-05-26 26 views
10

Bir kez daha "Bu olmamalı? *! # Hard" durumuyla karşılaşıyorum.MVC'de bir SelectList'e bağlanma

Sorun: Bir nesneyi oluşturmak için MVC'de bir form kullanmak istiyorum. Nesnenin unsurlarından biri, bir dizi sınırlı seçenek - bir açılır liste için mükemmel bir adaydır.

Modelimde bir SelectList'i ve Görünümüm'de bir açılır liste kullanırsam ve Model'i Create yöntemime geri göndermeye çalışırsam, "Eksik Yöntem İstisnası: Parametresiz yapıcı yok" hatasını alıyorum. nesne". MVC kaynak kodunu keşfederek, bir modele bağlanmak için Bağlayıcının önce onu oluşturabilmesi gerektiği ve bunun için bir varsayılan kurucu olmadığı için bir SelectList oluşturamayacağı anlaşılmaktadır. denetleyicisi için

public class DemoCreateViewModel 
{ 
    public SelectList Choice { get; set; } 
} 

: modeli için:

İşte basitleştirilmiş kod

// 
// GET: /Demo/Create 

public ActionResult Create() 
{ 
    DemoCreateViewModel data = new DemoCreateViewModel(); 
    data.Choice = new SelectList(new string[] { "Choice1", "Choice2", "Choice3" }); 
    ViewData.Model = data; 
    return View(); 
} 

// 
// POST: /Demo/Create 

[HttpPost] 
public ActionResult Create(DemoCreateViewModel form) 
{ 
    try 
    { 
     // TODO: Add insert logic here 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

Ve Manzara: Şimdi

<fieldset> 
    <legend>Fields</legend> 
    <%= Html.LabelFor(model => model.Choice) %> 
    <%= Html.DropDownListFor(model => model.Choice, Model.Choice) %> 
    <p> 
     <input type="submit" value="Create" /> 
    </p> 
</fieldset> 

, bundan emin oluyorum Bu çalışmayı 10 metre geriye düşürerek ve punting yaparak YAPIN: modelini baypas edin ve FormCo'ya geri bırakın Tüm alanları kendim kabul ediyorum ve onaylayın, ancak daha basit bir yol olmalı. Demek istediğim, bu kadar basit bir gereklilik. Bu işi MVC ModelBinding mimarisinde yapmanın bir yolu var mı? Eğer öyleyse, nedir? Ve değilse, nasıl olur?

Düzenleme: Yüzümde yumurta var, ama belki bu başka birine yardımcı olabilir. Biraz daha deney yaptım ve işe yarayan basit bir çözüm buldum.

Basit bir değer (select list value türüne bağlı olarak dize veya tamsayı) ve bağlandığınız model öğesi olarak adlandırın. Ardından, seçimlerin seçim listesi olarak ikinci bir eleman verin ve başka bir şey adlandırın. , Bunu yaparken

<%= Html.DropDownListFor(model => model.Choice, Model.Choices) %> 

, Gönder düğmesine doğru Choice dizeye şeklinde yapılan seçim bağlar:

public class DemoCreateViewModel 
{ 
    public string Choice { get; set; } 
    public SelectList Choices { get; set; } 
} 

Sonra View DropDownListFor deyimi haline gelir: Yani benim model oldu ve modeli ikinci Oluşturma yöntemine geri gönderir. Benim SelectList içermesini ViewBag kullanmak

@Html.DropDownListFor(model => model.Choice, 
         ViewBag.Choices as SelectList, 
         "-- Select an option--", 
         new { @class = "editor-textbox" }) 

Uyarı:

+0

Düzeltme dosyanızı gönderdiğiniz için teşekkür ederiz, benzer bir sorunla karşılaştık ve düzenlemenize yardımcı oldum – Chris

+0

Bunun yerine bunu bir IEnumerable veya SelectListItems listesine bağlayamıyor musunuz? –

cevap

5

İşte bir yaklaşımdır. Bu şekilde geri gönderdiğinizde, istemci tüm seçim listesini modelin bir parçası olarak sunucuya göndermez. Sonra

  public class DemoCreateViewModelForUpdate 
      { 
       public string Choice { get; set; } 
      } 

şunları yapabilirsiniz:

ViewBag.Choices = new SelectList(.... 
+1

* SelectList öğesini içermek için ViewBag kullandığımı dikkat edin. Bu şekilde geri gönderildiğinde, istemci tüm seçim listesini modelin bir parçası olarak sunucuya göndermez. * (1) Bu zaten olmaz; ve (2) eğer yapmış olsaydı, ViewBag kullanarak yayınlanmasını engellemezdi, sadece modele bağlanmasını engellerdi. –

0

SelectList özelliği olmadan sonrası eylem için farklı bir görünüm modeli oluşturmayı düşünün: Denetleyiciniz kodunda

, sadece görünüm torbasını ayarlamanız gerekir Model durumu geçersizse ve görünümü yeniden göstermek istiyorsanız, her zaman DemoCreateViewModelPost örneğinden bir DemoCreateViewModel örneğine eşleyin.Görüntülü görünüm model sınıfımda olması gereken görünümün gerektirdiği her şeyi tercih etme eğilimindeyim. Ayrı bir güncellemeyi yalnızca model görünümü kullanarak, işleri ince tutmak ve sunucuya geri dönüş için düzeltmeme izin verin. Size göre

, yapacağın:
  @Html.DropDownListFor(m => m.Choice, Model.Choices) 

önceki yanıtta olduğu gibi, bu yüzden hiçbir gereksiz veri gezi yuvarlamak istiyorum.