Переопределение местоположения для Razor View Engine - PullRequest
2 голосов
/ 24 марта 2012

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

Я использую маршруты типа / 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

1 Ответ

0 голосов
/ 21 февраля 2014

Взгляните на ViewLocationCache, чтобы добавить кеширование.

Это довольно просто использовать вот фрагмент из моего FindView:

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

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