2012-03-23 9 views
1

Ich bevorzuge es, mit einer Klasse pro Controller-Aktion in meinen MVC-Apps zu arbeiten, aber ich könnte meinen Ansichtsordner mit einem Ordner pro "Controller" strukturieren.Überschreibender Speicherort für Razor View Engine

Ich verwende Routen wie/Admin/Login, die zu einer Klasse namens AdminLoginController und/Admin/Index, die auf AdminIndexController zugeordnet werden würde. Allerdings möchte ich meinen Ansichtsordner so strukturieren, dass ich einen einzelnen Ordner namens Admin und dann zwei Dateien namens login.cshtml und index.cshtml habe.

Um dies zu tun sieht es so aus, als müsste ich die ViewEngine überschreiben. Ich habe es mit dem folgenden Code arbeiten:

public class MyViewEngine : RazorViewEngine 
{ 
    public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) 
    { 
     var controllerTypeName = controllerContext.RouteData.GetRequiredString("controller"); 
     var controllerParts =_GetControllerNameParts(controllerTypeName); 
     var folderName = controllerParts.Take(controllerParts.Length - 1).Aggregate((s1, s2) => s1 + s2); 
     viewName = controllerParts[controllerParts.Length - 1]; 
     var filename = _GetFilename(folderName, viewName, controllerContext); 

     return new ViewEngineResult(CreateView(controllerContext, filename, masterName), this); 
    } 

    private string[] _GetControllerNameParts(string controllerTypeName) 
    { 
     var r = new Regex(@" 
      (?<=[A-Z])(?=[A-Z][a-z]) | 
      (?<=[^A-Z])(?=[A-Z]) | 
      (?<=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace); 
     return r.Split(controllerTypeName); 
    } 

    private string _GetFilename(string folderName, string viewName, ControllerContext controllerContext) 
    { 
     var path = string.Format("~/Views/{0}/{1}.cshtml", folderName, viewName); 
     var filename = controllerContext.HttpContext.Server.MapPath(path); 
     if (File.Exists(filename)) { return path; } 
     return null; 
    } 
} 

Ich würde gerne wissen, ob es eine bessere Art und Weise, insbesondere die Basisansicht Motor eine Reihe von Caching usw. tut, die ich mag würde nehmen Vorteil von.

Hat jemand etwas ähnliches getan?

Danke, Matt

Antwort

0

Werfen Sie einen Blick auf die ViewLocationCache einige Caching hinzuzufügen.

Es ist ganz einfach, hier zu verwenden ist ein Ausschnitt aus meinem FindView:

 string cacheKey = CreateCacheKey(name, areaName, cacheKeyPrefix, specificPath, controllerName, skin, deviceManufacturerName, deviceName); 

     if (useCache) 
     { 
      return ViewLocationCache.GetViewLocation(controllerContext.HttpContext, cacheKey); 
     }