2011-10-16 2 views
5

In un'applicazione Web .NET a rasoio, sto provando a impostare a livello di programmazione il Layout. Non riesco a utilizzare _ViewStart.cshtml e non voglio impostare lo @{ Layout = "..." } su ogni pagina. Questo è quello che sono venuto con:.NET MVC 3 Layout a livello di programmazione

Una base WebViewPage classe:

public abstract class SitePage<T> : System.Web.Mvc.WebViewPage<T> 
{ 
    private object _layout; 

    public new dynamic Layout { get { return _layout; } } 

    public override void InitHelpers() 
    { 
     base.InitHelpers(); 
     _layout = "~/Themes/" + Settings.Theme + "/Views/_Layout.cshtml"; 
    } 
} 

E nell'applicazione web.config ho specificare tutte al fine di utilizzare questa pagina di base. Ma il Layout non è mai usato sembra. Cosa potrebbe essere sbagliato qui?

risposta

9

La classe WebViewPage eredita da WebPageBase che ha una proprietà chiamata Layout come:

public override string Layout { get; set; } 

è possibile ignorare la proprietà Layout, o cambiare la tua logica _layout per raggiungere il tuo scopo. Per esempio:

public abstract class SitePage<T> : System.Web.Mvc.WebViewPage<T> { 

    // set this modifier as protected, to make it accessible from view-pages 
    protected string _layout{ 
     get { 
      return base.Layout; 
     } 
     set { 
      base.Layout = value; 
     } 
    } 

    public override void InitHelpers() { 
     base.InitHelpers(); 
     _layout = "~/Themes/" + Settings.Theme + "/Views/_Layout.cshtml"; 
    } 
} 

e/o in una vista pagine, è possibile impostare anche:

@{ 
    _layout = "_Your_Special_Layout.cshtml"; 
} 

UPDATE: utilizzando un flag per evitare pila-over-flow nell'assegnare _layout più che una volta:

public abstract class SitePage<T> : System.Web.Mvc.WebViewPage<T> { 

    public bool LayoutAssigned { 
     get { 
      return (ViewBag.LayoutAssigned == true); 
     } 
     set { 
      ViewBag.LayoutAssigned = value; 
     } 
    } 

    // set this modifier as protected, to make it accessible from view-pages 
    protected string _layout{ 
     get { 
      return base.Layout; 
     } 
     set { 
      base.Layout = value; 
     } 
    } 

    public override void InitHelpers() { 
     base.InitHelpers(); 
     if(!LayoutAssigned) { 
      _layout = "~/Themes/" + Settings.Theme + "/Views/_Layout.cshtml"; 
      LayoutAssigned = true; 
     } 
    } 
} 
+0

Questo sembra causare uno stackoverflow. Quando il file Layout.cshtml contiene una vista parziale, InitHelpers viene richiamato e imposta il layout, quindi Layout.cshtml sembra essere nuovamente inizializzato e imposta nuovamente il layout, ecc. – jaap

+0

Hai ragione. Puoi fare qualcosa per risolvere questo. Uno di questi utilizza un flag booleano per verificare che il 'Layout' sia assegnato o meno. Che ho usato nel mio progetto, è che ho 3 classi base per i layout, le pagine di visualizzazione e le viste parziali. Inoltre puoi trovare altri modi speciali per il tuo progetto –

+0

Non riesco a parlare bene l'inglese. Mi dispiace se le mie frasi non sono comprensibili: D –

5

ho cercato di ottenere lo stesso poco fa mediante l'attuazione di un WebViewPage personalizzato, tuttavia cambiando WebViewPage.Layout all'interno della mia classe personalizzata non ha avuto un effetto (come hai anche scoperto).

Alla fine ho finito per cambiare la mia _ViewStart.cshtml di avere questo codice:

@{ 
    this.Layout = this.Request.QueryString["print"] == "1" 
     ? "~/Views/Layout/_Print.cshtml" 
     : "~/Views/Layout/_Layout.cshtml"; 
} 

Potrebbe non essere implementata come si voleva, ma certamente non mantenere le cose a secco e questo è il punto principale.

+0

Mi piace. Molto bene. – tofutim