2012-05-15 12 views
31

Attualmente sto provando a pubblicare un modulo composto da due viste fortemente tipizzate. Questa domanda è simile, ma non avere una risposta:Pubblica un modulo con più viste parziali

MVC 3 Razor Form Post w/ Multiple Strongly Typed Partial Views Not Binding

Quando ho presentare il modulo del modello presentato al controllore è sempre nullo. Ho passato un paio d'ore a cercare di farlo funzionare. Sembra che dovrebbe essere semplice. Mi sto perdendo qualcosa qui? Non ho bisogno di fare ajax solo bisogno di essere in grado di postare sul controller e visualizzare una nuova pagina.

Grazie

Ecco il mio codice della vista:

<div> 
    @using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"})) 
    { 
     ViewContext.FormContext.ValidationSummaryId = "valSumId"; 
     @Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } }); 
     @Html.Partial("_ReportOptions", Model.ReportOptions); 
     @Html.Partial("_TransactionSearchFields", new ViewDataDictionary(viewData) { Model = Model.SearchCriteria }); 
    } 

Ecco il codice nel controller:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult TransactionReport(TransactionReportRequest reportRequest) 
{ 
    var reportInfo = new List<TransactionReportItem>(); 

    if (ModelState.IsValid) 
    { 
     var reportData = _reportDataService.GetReportData(Search.MapToDomainSearchCriteria(reportRequest.SearchCriteria)); 
     if (reportData!=null) 
     { 
      reportInfo = reportData.ToList(); 
     } 
     return View(reportInfo); 
    } 
    return View(reportInfo); 
} 

I punti di vista parziali stessi sono abbastanza irrilevante, poiché tutto quello che sono fare sta aspettando e mostrando i loro modelli.

+0

Dov'è il tuo pulsante di invio? Deve essere all'interno del tag Form. Non sei sicuro di non averlo incluso o se è fuori dal tag –

risposta

49

partial non sono il modo di andare qui. Stai cercando EditorTemplates, questi sono fatti per quello che vuoi. In questo caso, le tue proprietà saranno ben legate al tuo modello (che invierai).

Il vostro principale View avrà questa forma (nota che è sufficiente usare EditorFor invece di Partial, in questo caso, è probabile che sarà necessario mettere quel parametro Viewdata nel ViewBag o giù di lì):

@using (Html.BeginForm("TransactionReport", "Reports", FormMethod.Post, new {id="report_request"})) 
{ 
    ViewContext.FormContext.ValidationSummaryId = "valSumId"; 
    @Html.ValidationSummary(false, "Please fix these error(s) and try again.", new Dictionary<string, object> { { "id", "valSumId" } }); 
    @Html.EditorFor(model => model.ReportOptions); 
    @Html.EditorFor(model = Model.SearchCriteria }); 
} 

Ora devi solo trascinare i tuoi partial nella cartella ~/Shared/EditorTemplates/ e rinominarli in modo che corrispondano al nome del modello per cui sono i modelli di editor.

Nella cartella ~/Shared/EditorTemplates/, creare una nuova "vista", esempio "SearchCriteria.cshtml". Dentro, metti come "modello" il tipo di classe con cui creare un modello di editor. Esempio (ad esempio classe ha proprietà Name e OtherCriteria):

@model MyNamespace.SearchCriteria 
<ul> 
    <!-- Note that I also use EditorFor for the properties; this way you can "nest" editor templates or create custom editor templates for system types (like DateTime or String or ...). --> 
    <li>@Html.LabelFor(m => m.Name): @Html.EditorFor(m => m.Name)</li> 
    <li>@Html.LabelFor(m => OtherCriteria): @Html.EditorFor(m => m.OtherCriteria</li> 
</ul> 

qualche buona lettura su di loro:

+1

Sì, questa è una soluzione molto migliore. Grails ha qualcosa di simile che avrei dovuto cercare su google (voglio dire binged) perché usa i termini grails :) Funziona alla grande! Grazie per l'aiuto! – Buzzer

+4

A volte è difficile trovare qualcosa quando non si conosce la terminologia corretta in una determinata tecnologia. – Styxxy

+0

lol ... è vero. Grazie ancora! – Buzzer

10

Sono d'accordo con @Styxxy e @Tony, Editor modelli sono la soluzione migliore. Tuttavia, il tuo problema è che stai alimentando un sottomodello alle viste parziali. Pertanto, quando la vista parziale esegue il rendering, non sa che fa parte di un modello più grande e non genera gli attributi di nome corretti.

Se si insiste sull'utilizzo di Partials anziché di Modelli di editor, quindi suggerisco di passare il modello solo ai partial, quindi fare in modo che ogni partial faccia Model.Whatever.Foo e generi gli attributi di nome corretti per il binding.

9

si dovrebbe aggiungere il prefisso ai campi del PartialView.Ciò consentirà il corretto collegamento dei dati.

Così, invece:

@Html.Partial("_ReportOptions", Model.ReportOptions); 

Usa:

@Html.Partial("_ReportOptions", Model.ReportOptions, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "ReportOptions" }}) 
1
@Html.Partial("_ReportOptions", Model.Contact, new ViewDataDictionary() 
      { 
       TemplateInfo = new TemplateInfo() 
        { 
         HtmlFieldPrefix = "Contact" 
        } 
      }) 

) 


@Html.Partial("_TransactionSearchFields", Model.SearchCriteria, new 
ViewDataDictionary() 
      { 
       TemplateInfo = new TemplateInfo() 
        { 
         HtmlFieldPrefix = "SearchCriteria" 
        } 
      })