Come posso specificare diversi layout nel file ViewStart del rasoio ASP.NET MVC 3?


313

Vorrei avere 2 layout separati nella mia applicazione. Supponiamo che uno sia per la sezione pubblica del sito Web e l'altro per la parte membro.

Per semplicità diciamo che tutta la logica di ciascuno di questi siti è racchiusa ordinatamente in 2 controller distinti.

  • PublicController
  • StaffController

E ciascuno di essi ha un layout corrispondente per tutta la vista sotto ciascuno.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Come faccio a utilizzare il file _ViewStart.cshtml per specificare che tutte le visualizzazioni / azioni in "Pubblico" utilizzano PublicLayout e tutto in "Staff" utilizza StaffLayout?

Grazie!


4
Per ogni evenienza: se si desidera rimuovere il layout per una determinata Razorvista, è sufficiente impostareLayout = null;
Leniel Maccaferri,

3
Proprio come un commento al tuo esempio, probabilmente non dovresti avere controller chiamati Public e Staff. I controller sono spesso implementati come punto di accesso all'azione simile a CRUD su determinate entità aziendali chiave, come EventController, UserController o simili. Se la tua applicazione è ragionevolmente grande, la responsabilità di un controllore pubblico / del personale sarebbe molto ampia. Considera invece le aree. msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx Potresti esserne consapevole ma qualcun altro che legge questo potrebbe avere un'idea sbagliata, quindi solo per la cronaca.
Alex,

Risposte:


558

È possibile inserire un _ViewStart.cshtmlfile all'interno della /Views/Publiccartella che sovrascriverà quello predefinito nella /Viewscartella e specificare il layout desiderato:

@{
    Layout = "~/Views/Shared/_PublicLayout.cshtml";
}

Per analogia potresti inserire un altro _ViewStart.cshtmlfile nella /Views/Staffcartella con:

@{
    Layout = "~/Views/Shared/_StaffLayout.cshtml";
}

È inoltre possibile specificare quale layout deve essere utilizzato quando si restituisce una vista all'interno di un'azione del controller, ma è per azione:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

Ancora un'altra possibilità è un filtro di azione personalizzato che avrebbe la precedenza sul layout. Come puoi vedere molte possibilità per raggiungere questo obiettivo. Spetta a te scegliere quale si adatta meglio al tuo scenario.


AGGIORNARE:

Come richiesto nella sezione commenti, ecco un esempio di filtro di azione che sceglierebbe una pagina principale:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

e quindi decorare un controller o un'azione con questo attributo personalizzato specificando il layout desiderato:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}

1
@DarinDimitrov Dove creerò LayoutInjecterAttribute. ? C'è qualche luogo particolare?
kbvishnu,

2
@VeeKeyBee, potresti inserirlo in una ActionFilterssottocartella.
Darin Dimitrov,

Un potenziale problema con LayoutInjecterAttribute: viene chiamato prima del OnExceptionmetodo del controller . Pertanto, se il controller fornisce un risultato di visualizzazione durante la gestione delle eccezioni, il layout non verrà impostato.
Jeff Sharp,

Come nuovo ragazzo di MVC, vorrei ringraziare per avermi insegnato molto in questa risposta. Tuttavia non capisco cosa stia succedendo dentro OnActionExecuted. Potete per favore aggiornare la risposta per me.
Imad,

29

Un altro metodo è quello di definire il layout all'interno della vista:

   @{
    Layout = "~/Views/Shared/_MyAdminLayout.cshtml";
    }

Altri modi per farlo, possono essere trovati qui , spero che questo aiuti qualcuno.


1
Questo non funzionerà - senza il _ViewStart.cshtml separato, la vista verrà comunque renderizzata all'interno del metodo @RenderBody () nell'altro layout.
Tillman32,

Questo! Perché tutti propongono questi processi estremamente complessi quando tutto ciò che devi fare è questo!
George Harnwell,

15

Questo metodo è il modo più semplice per i principianti di controllare il rendering dei layout nell'applicazione ASP.NET MVC. Possiamo identificare il controller e rendere i layout come controller par, per fare ciò possiamo scrivere il nostro codice nel file _ViewStart nella directory principale della cartella Views. Di seguito è riportato un esempio che mostra come si può fare.

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

Leggi l'articolo completo qui "Come eseguire il rendering di layout diversi in ASP.NET MVC"

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.