Come impostare un layout Razor in MVC tramite un filtro di attributo?
-
27-09-2019 - |
Domanda
mi piacerebbe impostare un default Razor aspetto attraverso il codice sia in un controller di base o di un attributo. E 'stato menzionato nella documentazione che questo è possibile, ma non riesco a capire come si fa.
So che c'è il parametro masterpage al metodo View disponibile, ma vorrei tutte le viste restituiti da un controller di avere questo valore impostato automaticamente.
E no, non è possibile utilizzare _ViewStart per questo dal mio punto di vista stanno per essere in diversi luoghi (questo non è un normale sito di configurazione MVC).
Grazie
Soluzione
Credo che si può solo scrivere un ActionFilter come ...
public class YourCustomLayoutAttribute : ActionFilterAttribute, IResultFilter
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
var viewResult = filterContext.Result as ViewResult;
if(viewResult != null)
{
// switch the layout
// I assume Razor will follow convention and take the "MasterName" property and change the layout based on that.
viewResult.MasterName = "CustomLayout";
}
}
}
Ho appena scritto questo codice per la sede dei miei pantaloni senza compilatore in modo che probabilmente non si compila, ma probabilmente ottenere l'idea. Penso IResultFilter è l'interfaccia corretta che si desidera, si dispone di metodi che vengono eseguiti a destra prima la vista è resa. Se questo è corretto, si dovrebbe essere in grado di modificare il MasterName per la vista che sta per essere reso al volo.
Questa sarebbe l'utilizzo di codice di controllo.
[YourCustomLayout] // this should trigger your custom action result for all actions
public class MyController : Controller
{
public ActionResult Index()
{
return View("Index", "MainLayout"); // even if you were to use the overload to set a master, the action result should override it as it executes later in the pipeline.
}
}
Altri suggerimenti
Il modo più semplice che posso pensare di fare questo è di avere i controller derivano da una classe base personalizzata che l'override del metodo Vista:
public class MyControllerBase : Controller {
public override ViewResult View(string viewName, string masterName, object model) {
if(String.IsNullOrEmpty(masterName)) {
masterName = GetDefaultLayout();
}
base.View(viewName, masterName, model);
}
public virtual string GetDefaultLayout() {
return // your default layout here
}
}
Nel codice di cui sopra si potrebbe esplicitamente impostare la masterName a un valore hardcoded. O il vostro controller potrebbe eseguire l'override del metodo per fornire un layout di controllo specifico. Oppure si potrebbe leggere da qualche attributo Controller, qualcosa di simile a:
masterName = GetType().GetCustomAttributes().
OfType<MyCustomAttribute>().FirstOrDefault().DefaultLayoutPage;
Naturalmente dovreste creare il MyCustomAttribute
.