2012-05-11 26 views
5

ile MVC3 Razor httppost return complex objects child collections'dan itibaren bir takip sorusudur.mvc3 jilet editörleri, soyut sınıfları

Verdiğim örnek çok basitti. Çocuk koleksiyonu aslında hepsi soyut bir temel sınıftan gelen nesnelerin bir koleksiyonudur. Yani koleksiyonun temel sınıfların bir listesi var.

Her türetilmiş sınıf için bir şablon oluşturdum ve çocuk türündeyse kullanmayı denedim, sonra şablon adını bir dize olarak verdim. Şablonlar görüntüye işlenir, ancak geri postada gösterilmez.

Doğru şablon seçmek için editöre ilişkin bitin şablonlarla nasıl kullanıldığından emin değilim ve bilgileri ana kapsayıcı içindeki alt nesneler olarak yeniden sıralamaya başlayın.

cevap

8

Özel bir model bağlayıcı kullanabilirsiniz. Bir örnek alalım.

Modeli:

public class MyViewModel 
{ 
    public IList<BaseClass> Children { get; set; } 
} 

public abstract class BaseClass 
{ 
    public int Id { get; set; } 

    [HiddenInput(DisplayValue = false)] 
    public string ModelType 
    { 
     get { return GetType().FullName; } 
    } 
} 

public class Derived1 : BaseClass 
{ 
    public string Derived1Property { get; set; } 
} 

public class Derived2 : BaseClass 
{ 
    public string Derived2Property { get; set; } 
} 

Denetleyici:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel 
     { 
      Children = new BaseClass[] 
      { 
       new Derived1 { Id = 1, Derived1Property = "prop1" }, 
       new Derived2 { Id = 2, Derived2Property = "prop2" }, 
      } 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     // everything will be fine and dandy here 
     ... 
    } 
} 

View (~/Views/Home/Index.cshtml): Dervied1 türü için

@model MyViewModel 

@using (Html.BeginForm()) 
{ 
    for (int i = 0; i < Model.Children.Count; i++) 
    { 
     @Html.EditorFor(x => x.Children[i].ModelType) 
     <div> 
      @Html.EditorFor(x => x.Children[i].Id) 
      @Html.EditorFor(x => x.Children[i])  
     </div> 
    } 

    <button type="submit">OK</button> 
} 

Editör şablonu (~/Views/Home/EditorTemplates/Derived1.cshtml):

@model Derived1 
@Html.EditorFor(x => x.Derived1Property) 

ve Dervied2 türü (~/Views/Home/EditorTemplates/Derived2.cshtml) için editör şablonu: bıraktı Şimdi

@model Derived2 
@Html.EditorFor(x => x.Derived2Property) 

tüm koleksiyonunda uygun türü örneğini gizli alan değerini kullanacaktır özel modeli cilt geçerli:

Application_Start tescil edilecektir
public class BaseClassModelBinder : DefaultModelBinder 
{ 
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
    { 
     var typeValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ModelType"); 
     var type = Type.GetType(
      (string)typeValue.ConvertTo(typeof(string)), 
      true 
     ); 
     var model = Activator.CreateInstance(type); 
     bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type); 
     return model; 
    } 
} 

:

ModelBinders.Binders.Add(typeof(BaseClass), new BaseClassModelBinder()); 
+0

harika ... bu işe yaradı ... İşe geri dönmek ve dizüstü bilgisayarımı harika göründüğü için denemek zorunda kaldım ... hafta sonunu da yaptım, daha başlamadan önce – Jon