2011-04-18 8 views
25

C# 'da bir ASP.NET MVC 3 uygulaması geliştiriyorum ve Razor kullanıyorum. Şimdi, Kontrolör tarafından View/View'den alınan/alınan ViewModels aracılığıyla nesnelerin bağlanması ile ilgili bir sorunla uğraşıyorum. Açıklığa kavuşturalım. ContainerViewModel View verileri iletmek için kullanılırYuvalanmış ViewModels'i MVC3'teki View to Controller'a nasıl bağlarım?

public class ContainerViewModel 
{ 
    public int ContainerId {get; set;} 
    public string ContainerName {get; set;} 
    public List<ItemPostModel> ItemData {get; set;} 
} 

public class ItemPostModel 
{ 
    public int ItemId {get; set;} 
    public string ItemName {get; set;} 
    public int ItemValue {get; set;} 
} 

: Aşağıdaki ViewModels var. ContainerId ve ContainerName özellikleri yalnızca görüntüleme amacıyla kullanılır. List<ItemPostModel> özelliğinin Form kullanılarak doldurulması gerekir. aşağıdaki gibi

<strong>@Model.ContainerName</strong> 


@using (Html.BeginForm()) 
{ 
    <fieldset> 
    @foreach(var item in Model.ItemData) 
    { 
     @Html.TextBox(item.ItemId); 
     @Html.TextBox(item.ItemName); 
     @Html.TextBox(item.ItemValue); 

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

Kontrolöreylem yöntemlerini tekabül şunlardır: Görünüm şuna benzer (bir basitleştirilmiş versiyonu)

public ActionResult UpdateItems() 
{ 
    //fill in the ContainerViewModel lcontainer 

    return View("UpdateItems", lcontainer); 
} 

[HttpPost] 
public ActionResult UpdateItems(int containerId, ItemPostModel itemData) 
{ 
    //store itemData into repository 
} 

sorun olduğunu bu kodu ile ItemPostModel itemData, Post ActionMethod UpdateItems için her zaman boş. containerId doğru şekilde iletildi. Kontrol cihazında aşağıdaki kodu kullanırsam aynı sonuç (açıkçası DRY değil);

[HttpPost] 
public ActionResult UpdateItems(ContainerViewModel container) 
{ 
    //extract itemData from ContainerViewModel container 
    //store itemData into repository 
} 

nasıl ben List<ItemPostModel> saklanan form öğeleri istediğiniz uygulamayı "öğretmek" olabilir? ModelBinder'u değiştirecek miyim yoksa bu görevi gerçekleştirmenin daha basit bir yolu var mı? Cevaplarınız için herkese teşekkürler.

cevap

24

Görünümde döngüler yazmayın. Kullanım editörü şablonları:

<strong>@Model.ContainerName</strong> 
@using (Html.BeginForm()) 
{ 
    <fieldset> 
     @Html.EditorFor(x => x.ItemData) 
     <input type="submit" value="Save" /> 
    </fieldset> 
} 

ve ilgili editör şablonu içinde

( ~/Views/Shared/EditorTemplates/ItemPostModel.cshtml):

[HttpPost] 
public ActionResult UpdateItems(
    int containerId, 
    [Bind(Prefix = "ItemData")]ItemPostModel itemData 
) 
{ 
    //store itemData into repository 
} 

ve bu:

@model ItemPostModel 
@Html.TextBox(x => x.ItemId) 
@Html.TextBox(x => x.ItemName) 
@Html.TextBox(x => x.ItemValue) 

Ve denetleyici eylem Eğer öneği gerekebilir

hemen hemen hepsi olmalı. Editör şablonu, işe bağlanma için uygun giriş alanı adlarını oluşturmaya özen gösterir.

+0

Cevabınız için teşekkür ederiz. ** ~/Görünümler/Paylaşılan/EditorTemplates/ItemPostModel.cshtml ** kısmi bir görünüm değil mi? Dahası, neden Görünümde foreach kullanmamanızı tavsiye ediyorsunuz? Kod nuggets ile html "bozmak" değil mi? Teşekkürler – CiccioMiami

+0

@Francesco, evet, 'ItemPostModel.cshtml' kısmi. Ayrıca, görünüm alanlarındaki döngüleri kullanmamayı öneririm çünkü giriş alanları için uygun isimler oluşturmaya özen gösteren editör şablonları vardır. Bu sadece bu kodu kolaylaştırır, ancak bu değerleri kontrolöre geri almak istediğinizde varsayılan model bağlayıcı ile çalışır. –

+1

Öncelikle vurguladığım önemli bir nokta, EditorTemplate'in tek bir ItemPostModel (koleksiyona değil) olmasına rağmen, EditorFor yardımcılarının otomatik olarak ItemPostModel koleksiyonunu kullanmasıdır. – PenFold

İlgili konular