Visualizza una vista da un altro controller in ASP.NET MVC


248

È possibile visualizzare una vista da un altro controller?

Ad esempio, ho un CategoriesControllere un Category/NotFound.aspxpunto di vista. Mentre nel CategoriesController, posso facilmente tornare View("NotFound").

Ora dì che ho un ProductsControllere un'azione e visualizzare per aggiungere un prodotto. Tuttavia, questa azione richiede che abbiamo una categoria a cui aggiungere il prodotto. Ad esempio Products/Add/?catid=10,.

Se non riesco a trovare la Categoria in base catid, voglio mostrare la NotFoundvista dal controller Categorie invece di creare una CategoryNotFoundvista nel controller Prodotti.

È possibile o sto strutturando le cose nel modo sbagliato? C'è un buon modo per farlo?

Risposte:


283

Sì. Per impostazione predefinita, ASP.NET MVC effettua il check-in prima \Views\[Controller_Dir]\, ma successivamente, se non trova la vista, effettua il check-in \Views\Shared.

La directory condivisa è lì appositamente per condividere le visualizzazioni su più controller. Aggiungi la tua vista alla sottodirectory Shared e sei a posto.

In tal caso è return View("~/Views/Wherever/SomeDir/MyView.aspx")possibile restituire qualsiasi visualizzazione desiderata.


Grazie, sembra la soluzione che dovrei usare. Mi chiedo comunque se è possibile visualizzare una vista da un altro controller. Immagino che questo violi alcune regole in MVC?
dtc,

1
Nella situazione descritta in precedenza, sì, dovresti utilizzare la cartella condivisa.
Jonathan Freeland,

69
Sì, anche questo è possibile. Se si restituisce Visualizza ("~ / Views / Wherever / SomeDir / MyView.aspx") È possibile restituire qualsiasi visualizzazione desiderata. Ciò non viola di per sé nessuna regola particolare, tuttavia, ASP.Net MVC è tutto incentrato sulla "convenzione sulla congfigurazione". In altre parole, il framework è costruito per funzionare automaticamente utilizzando determinate convenzioni e dovresti utilizzarlo dove possibile.
womp,

1
Grazie per la spiegazione Non sapevo che Views potesse essere chiamato così. La directory condivisa ovviamente funziona perfettamente :)
dtc

1
Non ero in un controller, quindi ho dovuto usare new ViewResult { ViewName = "~/Views/Error/Unauthorised.cshtml" };e ha funzionato
Nacht il

162

Puoi usare:

return View("../Category/NotFound", model);

È stato testato in ASP.NET MVC 3, ma dovrebbe funzionare anche in ASP.NET MVC 2.


3
Funziona in MVC 2 e si è rivelata la soluzione più pulita per una situazione insolita con cui ho a che fare.
Todd Menier,

3
Resharper segnalerà quel link come errore ma funziona ancora.
CodeMonkeyKing,

1
@CodeMonkeyKing - Resharper 7 (in VS2012) identifica correttamente un percorso formattato come "~/Views/Category/NotFound.cshtml".
Richard Ev,

Vale la pena notare: questa soluzione funziona con le modalità di visualizzazione, ad esempio se si dispone di una vista "/Category/NotFound.Mobile.cshtml".
BenWillkommen,

55

Si è possibile. Restituisce un RedirectToAction()metodo come questo:

return RedirectToAction("ActionOrViewName", "ControllerName");

1
Credo che questo dovrebbe andare come RedirectToAction ("ActionOrView", "Controller", null), altrimenti il ​​secondo parametro è routeValues
Zoran P.

Ma in questo caso, devi effettivamente scrivere l'azione nel controller, a differenza della soluzione View.
tobbenb3

@ tobbenb3 Questa è una soluzione molto migliore rispetto al risultato hardcoding. In entrambi i casi non dovresti passare una stringa di percorso.
perustaja,

34

Ci hai provato RedirectToAction?


1
Direi che questo è l'MVC per chiunque non desideri la vista nelle sue cartelle condivise, nota che per tutte le altre soluzioni (come l'uso di percorsi diretti) chiunque tenti di ricodificare le viste non dovrà prendere in considerazione che viene utilizzato anche in un altro controller, con conseguente comportamento imprevedibile
yoel halb

4
che ne dici senza reindirizzare?
Luckyy,

soluzione
decisamente

Questa soluzione richiede un'azione sul controller, View (directPath) esegue il rendering dell'output senza alcuna azione. Quando aggiungi un'azione, devi pensare di nasconderla dall'accesso diretto tramite url, genererà un passaggio nella cronologia del browser ecc. Ma sì, è la mia strada da percorrere.
Jan Zahradník,

3
RedirectToAction invia un codice di risposta 302 al browser. Ciò non è appropriato quando si tenta di mostrare una pagina 404 non trovata. Cioè, questa soluzione sembra funzionare ma confonderà i motori di ricerca.
NightOwl888,

20

Si, puoi. Restituisci un'azione come questa:

return RedirectToAction("View", "Name of Controller");

Un esempio:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees");

Questo approccio chiamerà il metodo GET

Inoltre potresti passare valori ad azioni come questa:

return RedirectToAction("Details/" + id.ToString(), "FullTimeEmployees", new {id = id.ToString(), viewtype = "extended" });

come invio un oggetto con questo approccio?
Djeroen,

Dai un'occhiata a @Djeroen
ignacio chiazzo,

5
Non stai restituendo una vista, stai chiamando un'azione.
0014

Soprattutto è stato utile per me.
anil shrestha,

5

Puoi anche chiamare qualsiasi controller da JavaScript / jQuery . Supponi di avere un controller che restituisce 404 o qualche altro controllo / pagina utente. Quindi, su qualche azione, dal tuo codice client, puoi chiamare un indirizzo che attiverà il tuo controller e restituirà il risultato in formato HTML il tuo codice client può prendere questo risultato restituito e inserirlo dove vuoi nella tua pagina ...


Non lo sapevo. Sembra che sia qualcosa che potrei usare in futuro. Sì, mvc rocks :)
dtc,

1

Con questo codice è possibile ottenere qualsiasi controller:

var controller = DependencyResolver.Current.GetService<ControllerB>();
controller.ControllerContext = new ControllerContext(this.Request.RequestContext, 
controller);

Traduzione: Con questo codice è possibile ottenere qualsiasi controller: [codice], Saluti,
Robert Columbia

3
Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo riguardo a come e / o perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
Nic3500,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.