2012-03-23 13 views
17

Sto cercando di implementare una custom RazorViewEngine. Fondamentalmente ho due siti con lo stesso codice di base. Le differenze sono che sembrano diverse. Voglio sovrascrivere il motore di visualizzazione standard per fare in modo che MVC guardi in due posizioni distinte per le visualizzazioni, i layout, ecc. Per la società A e l'altro per la società B. La società A conterrà le viste principali e la vista dell'azienda B sostituirà questi master. Quindi voglio che il View Engine guardi nella posizione B per una vista, un layout, master o parziale se lo trova e poi lo restituisce, se non lo trova lo voglio come predefinito per le viste dell'azienda A come predefinito. Ovviamente l'azienda A cercherà solo nella propria cartella.Come implementare un RazorViewEngine personalizzato per trovare viste in posizioni non standard?

Ok al nocciolo della questione: ho trovato questo sito: http://www.aspnetwiki.com/mvc-3-razor:extending-the-view-engine

Prima domanda, è questo il modo migliore per raggiungere questo obiettivo?

In secondo luogo ho bisogno di ignorare i metodi CreatePartial, CreateView, FindPartial e FindView?

Aggiornamento

Ok ho capito la seconda domanda che mi, i metodi che voglio ignorare sono CreateView e CreatePartialView come a questo punto è costruito la stringa vista e posso perderci tempo.

+0

Vuoi mantenere due siti Web diversi nella stessa cartella? –

+0

Quello che sto dicendo è che voglio che le viste siano in cartelle separate ma che condividano lo stesso controller/modello. – Liam

risposta

13

Ok, alla fine ho optato per un approccio dettagliato qui: http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx

grazie alle @Adriano per le risposte e puntatori, ma alla fine credo che questo approccio si adatta alle mie esigenze meglio. L'approccio seguente mi consente di mantenere la funzionalità standard, ma di creare una nuova posizione di visualizzazione con priorità più alta da cercare.

public class Travel2ViewEngine : RazorViewEngine 
{ 
    protected BrandNameEnum BrandName; 
    private string[] _newAreaViewLocations = new string[] { 
     "~/Areas/{2}/%1Views/{1}/{0}.cshtml", 
     "~/Areas/{2}/%1Views/{1}/{0}.vbhtml", 
     "~/Areas/{2}/%1Views//Shared/{0}.cshtml", 
     "~/Areas/{2}/%1Views//Shared/{0}.vbhtml" 
    }; 

    private string[] _newAreaMasterLocations = new string[] { 
     "~/Areas/{2}/%1Views/{1}/{0}.cshtml", 
     "~/Areas/{2}/%1Views/{1}/{0}.vbhtml", 
     "~/Areas/{2}/%1Views/Shared/{0}.cshtml", 
     "~/Areas/{2}/%1Views/Shared/{0}.vbhtml" 
    }; 

    private string[] _newAreaPartialViewLocations = new string[] { 
     "~/Areas/{2}/%1Views/{1}/{0}.cshtml", 
     "~/Areas/{2}/%1Views/{1}/{0}.vbhtml", 
     "~/Areas/{2}/%1Views/Shared/{0}.cshtml", 
     "~/Areas/{2}/%1Views/Shared/{0}.vbhtml" 
    }; 

    private string[] _newViewLocations = new string[] { 
     "~/%1Views/{1}/{0}.cshtml", 
     "~/%1Views/{1}/{0}.vbhtml", 
     "~/%1Views/Shared/{0}.cshtml", 
     "~/%1Views/Shared/{0}.vbhtml" 
    }; 

    private string[] _newMasterLocations = new string[] { 
     "~/%1Views/{1}/{0}.cshtml", 
     "~/%1Views/{1}/{0}.vbhtml", 
     "~/%1Views/Shared/{0}.cshtml", 
     "~/%1Views/Shared/{0}.vbhtml" 
    }; 

    private string[] _newPartialViewLocations = new string[] { 
     "~/%1Views/{1}/{0}.cshtml", 
     "~/%1Views/{1}/{0}.vbhtml", 
     "~/%1Views/Shared/{0}.cshtml", 
     "~/%1Views/Shared/{0}.vbhtml" 
    }; 

    public Travel2ViewEngine() 
     : base() 
    { 
     Enum.TryParse<BrandNameEnum>(Travel2.WebUI.Properties.Settings.Default.BrandName, out BrandName); 

     AreaViewLocationFormats = AppendLocationFormats(_newAreaViewLocations, AreaViewLocationFormats); 

     AreaMasterLocationFormats = AppendLocationFormats(_newAreaMasterLocations, AreaMasterLocationFormats); 

     AreaPartialViewLocationFormats = AppendLocationFormats(_newAreaPartialViewLocations, AreaPartialViewLocationFormats); 

     ViewLocationFormats = AppendLocationFormats(_newViewLocations, ViewLocationFormats); 

     MasterLocationFormats = AppendLocationFormats(_newMasterLocations, MasterLocationFormats); 

     PartialViewLocationFormats = AppendLocationFormats(_newPartialViewLocations, PartialViewLocationFormats); 
    } 

    private string[] AppendLocationFormats(string[] newLocations, string[] defaultLocations) 
    { 
     List<string> viewLocations = new List<string>(); 
     viewLocations.AddRange(newLocations); 
     viewLocations.AddRange(defaultLocations); 
     return viewLocations.ToArray(); 
    } 

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) 
    { 
     return base.CreateView(controllerContext, viewPath.Replace("%1", BrandName.ToString()), masterPath); 
    } 

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath) 
    { 
     return base.CreatePartialView(controllerContext, partialPath.Replace("%1", BrandName.ToString())); 
    } 

    protected override bool FileExists(ControllerContext controllerContext, string virtualPath) 
    { 
     return base.FileExists(controllerContext, virtualPath.Replace("%1", BrandName.ToString())); 
    } 
} 

quindi registrarlo in Gloabal.asax

protected void Application_Start(object sender, EventArgs e) 
{ 
    RegisterRoutes(RouteTable.Routes); 


    //Register our customer view engine to control T2 and TBag views and over ridding 
    ViewEngines.Engines.Clear(); 
    ViewEngines.Engines.Add(new Travel2ViewEngine()); 
} 
5

Sì, questo è il modo, ma non è necessario sovrascrivere tali metodi. RazorViewEngine eredita da VirtualPathProviderViewEngine in modo che tu possa utilizzare le sue proprietà per impostare la posizione delle tue visualizzazioni.

Per un esempio leggere Creating your first MVC ViewEngine e How to set a Default Route (To an Area) in MVC.

+0

Questo sembra interessante ma non sono convinto che faccia esattamente quello che voglio che faccia, la documentazione è un po 'scarsa, hai un esempio che puoi pubblicare? – Liam

+1

È solo un piccolo esempio, ma: http://coderjournal.com/2009/05/creating-your-first-mvc-viewengine/ e questo link molto bello qui su SO: http://stackoverflow.com/questions/2140208/how-to-set-a-default-route-to-an-area-in-mvc –

+0

Ho appena trovato il primo da solo! Ta! – Liam

1

Ecco la mia risposta: aggiungere questo alla tua global.ascx

 ViewEngines.Engines.Clear(); 
     var customEngine = new RazorViewEngine(); 
     customEngine.PartialViewLocationFormats = new string[] 
     { 
      "~/Views/{1}/{0}.cshtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Partial/{0}.cshtml", 
      "~/Views/Partial/{1}/{0}.cshtml" 
     }; 



     customEngine.ViewLocationFormats = new string[] 
     { 
      "~/Views/{1}/{0}.cshtml", 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Controller/{1}/{0}.cshtml" 
     }; 

     customEngine.MasterLocationFormats = new string[] 
     { 
      "~/Views/Shared/{0}.cshtml", 
      "~/Views/Layout/{0}.cshtml" 
     }; 

     ViewEngines.Engines.Add(customEngine); 

quelle sono le cartelle in cui i controlli di rasoio le vostre opinioni.

Fammi sapere se funziona.

Problemi correlati