Modelli complessi e viste parziali: problemi di associazione dei modelli in ASP.NET MVC 3

Ho 2 modelli nell’applicazione MVC 3 di esempio, SimpleModel e ComplexModel , mostrati di seguito:

 public class SimpleModel { public string Status { get; set; } } public class ComplexModel { public ComplexModel() { Simple = new SimpleModel(); } public SimpleModel Simple{ get; set; } } 

Ho definito le viste per questi modelli:

_SimplePartial.cshtml :

 @model SimpleModel @Html.LabelFor(model => model.Status) @Html.EditorFor(model => model.Status) 

e Complex.cshtml :

 @model ComplexModel @using (Html.BeginForm()) { @Html.Partial("_SimplePartial", Model.Simple)  } 

Dopo aver inviato il modulo, con il valore casuale inserito nel campo Status , il valore non è vincolato al mio modello. Il campo Status è NULL quando controllo il modello nell’azione del mio controller:

 [HttpPost] public ActionResult Complex(ComplexModel model) { // model.Simple.Status is NULL, why ? } 

Perché non è legato? Non voglio ereditare modelli. Devo scrivere i miei raccoglitori modello personalizzati per un caso così semplice?

Saluti.

Invece di:

 @Html.Partial("_SimplePartial", Model.Simple) 

Ti consiglierei di utilizzare i modelli di editor:

 @model ComplexModel @using (Html.BeginForm()) { @Html.EditorFor(x => x.Simple)  } 

e quindi inserire il partial parziale all’interno di ~/Views/Shared/EditorTemplates/SimpleModel.cshtml o all’interno di ~/Views/Home/EditorTemplates/SimpleModel.cshtml dove Home è il nome del controller:

 @model SimpleModel @Html.LabelFor(model => model.Status) @Html.EditorFor(model => model.Status) 

Ovviamente se preferisci avere il parziale in qualche luogo speciale e non seguire le convenzioni (perché vorresti?) Potresti specificare la posizione:

 @Html.EditorFor(x => x.Simple, "~/Views/SomeUnexpectedLocation/_SimplePartial.cshtml") 

allora tutto andrà a posto come previsto.

Come suggerisce Daniel Hall nel suo blog , passare un ViewDataDictionary con un TemplateInfo dove HtmlFieldPrefix è impostato sul nome della proprietà SimpleModel:

  @Html.Partial("_SimplePartial", Model.Simple, new ViewDataDictionary(ViewData) { TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Simple" } })