2012-03-23 3 views
1

Я предпочитаю работать с одним классом на каждое действие контроллера в своих приложениях MVC, однако я должен был бы структурировать свою папку просмотра с одной папкой на «контроллер».Переопределение местоположения просмотра для механизма просмотра Razor

Я использую такие маршруты, как/Admin/Login, который сопоставляется с классом AdminLoginController и/Admin/Index, который будет отображаться в AdminIndexController. Тем не менее, я хотел бы структурировать свою папку просмотра, чтобы у меня была одна папка с именем Admin, а затем 2 файла с именем login.cshtml и index.cshtml.

Для этого мне кажется, что мне нужно переопределить ViewEngine. Я получил это работает со следующим кодом:

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; 
    } 
} 

Я хотел бы знать, если есть лучший способ, в частности, основной вид двигатель делает кучу кэширования и т.д., которые я хотел бы взять преимущество.

Кто-нибудь сделал что-то подобное?

Спасибо, Matt

ответ

0

Посмотрите на ViewLocationCache добавить некоторое кэширование.

Это довольно простой в использовании здесь отрывок из моей FindView:

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

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