16

Ho creato la seguente custom ActionResult che restituisce più viste parziali.Custom ActionResult equivalente Modello per tutte le PartialView

public class MultiplePartialViewsResult : ActionResult 
{ 
    private const string Separator = "-"; 
    private PartialViewResult[] _partialViews; 

    public MultiplePartialViewsResult(params PartialViewResult[] partialViews) 
    { 
     _partialViews = partialViews; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     foreach (var partialView in _partialViews) 
     { 
      partialView.ExecuteResult(context); 
      context.HttpContext.Response.Output.Write(Separator); 
     } 
    } 
} 

E poi lo uso come segue:

return new MultiplePartialViewsResult(
      PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }), 
      PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 })); 

Ma se metto punto di interruzione nel costruttore MultiplePartialViewsResult s' vedo che il modello in entrambi i casi è uguale 2.0. Sostituisce tutti i modelli con l'ultimo modello specificato in una matrice.

Provare a creare coppie PartialViews nel metodo e assegnarlo alla variabile. Quindi noterai che condividono tutti un modello equivalente.

+1

Sì, è corretto. Se si sta tentando di restituire due 'model's a una vista, creare un' modello di vista' che contenga entrambi i modelli che si desidera inviare e rendere il modello della vista il nuovo 'ViewModel' –

+0

Questo è il punto che sto cercando di restituire a molte visualizzazioni.Idea si basa su questo post in cui l'autore indica che i modelli possono essere distinti. https://www.simple-talk.com/dotnet/asp.net/revisiting-partial-view-rendering-in-asp.net-mvc/ – Maximus

+1

Controllare le ultime cose? Dice di usare 'view model' condiviso da entrambi' partial view'. –

risposta

6

È possibile inizializzare l'oggettoMultiplePartialViewsResult nel modo seguente con nuovo proprioViewdata/ViewData.Model casi (funziona bene per me):

return new MultiplePartialViewsResult(
    //PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }), 
    //PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 }) 
    new PartialViewResult() { ViewName = "~/Views/RowSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 1.0 } } }, 
    new PartialViewResult() { ViewName = "~/Views/ColumnSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 2.0 } } } 
); 

azione personalizzata Risultato:

public class MultiplePartialViewsResult : ActionResult { 
    private const string Separator = "-"; 
    private PartialViewResult[] _partialViews; 

    public MultiplePartialViewsResult(params PartialViewResult[] partialViews) { 
     _partialViews = partialViews; 
    } 

    public override void ExecuteResult(ControllerContext context) { 
     foreach(var partialView in _partialViews) { 
      partialView.ExecuteResult(context); 
      context.HttpContext.Response.Output.Write(Separator); 
     } 
    } 
} 

Controller:

public ActionResult Index() { 
    return View(); 
} 
public ActionResult FakeAction() { 
    return new MultiplePartialViewsResult(
     //PartialView("~/Views/RowSumView.cshtml", new List<double>() { 1.0 }), 
     //PartialView("~/Views/ColumnSumView.cshtml", new List<double>() { 2.0 }) 
     new PartialViewResult() { ViewName = "~/Views/RowSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 1.0 } } }, 
     new PartialViewResult() { ViewName = "~/Views/ColumnSumView.cshtml", ViewData = new ViewDataDictionary() { Model = new List<double>() { 2.0 } } } 
    ); 
} 

Visualizzazioni:

Indice:

@Html.Action("FakeAction") 

ColumnSumView.cshtml/RowSumView.cshtml:

@model List<double> 
<ul> 
    @foreach(double item in Model) { 
     <li>@item</li> 
    } 
</ul> 
+0

Questa è una soluzione, ma mi chiedo perché il mio esempio non funzioni. C'è un approccio migliore per passare più viste parziali? – Maximus

+0

Sembra che sia correlato al possesso di un oggetto ViewData/Model durante il rendering di PartialView (un singolo ViewData per un ActionResult). Forse, questo è un comportamento previsto. Cercherò di verificare se esiste una soluzione migliore. Per ora, è possibile utilizzare il mio approccio suggerito e inizializzare sempre ogni ActionResult/PartialViewResult con una nuova istanza ViewData/Model. – Mikhail

+3

Questo succede a causa del ['PartialView'] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Controller.cs) helper del controller che Maximum ha utilizzato per creare ogni risultato parziale. Tale helper imposterà il modello in ViewData.Model dove ViewData è una proprietà in [il controller] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ControllerBase.cs). Chiamando due volte 'PartialResult' si sovrascrive ViewData.Model –

Problemi correlati