ASP .NET MVC VirtualPathProvider - PullRequest
       27

ASP .NET MVC VirtualPathProvider

2 голосов
/ 18 августа 2010

Я пишу VirtualPathProvider для динамической загрузки моих представлений MVC, которые расположены в другом каталоге. Я успешно перехватываю вызов перед MVC (в FileExists), но в моем VirtualPathProvider я получаю необработанный, предварительно перенаправленный URL, например:

~/Apps/Administration/Account/LogOn

Лично я знаю, что MVC будет искать

~/Apps/Administration/Views/Account/LogOn.aspx

и что я должен читать содержимое файла из

D:\SomeOtherNonWebRootDirectory\Apps\Administration\Views\Account\LogOn.aspx

но я бы не стал жестко кодировать логику, чтобы «добавить каталог с именем Views и добавить aspx в конец».

Где хранится эта логика и как я могу получить ее в своем провайдере виртуальных путей?

Спасибо. Извините, если мне неясно.

Ответы [ 3 ]

4 голосов
/ 18 августа 2010

Отредактировано

Вам необходимо создать класс, который наследует WebFormViewEngine и устанавливает свойство ViewLocationFormats (унаследованное от VirtualPathProviderViewEngine).

Значения по умолчанию можно найти в источнике MVCcode:

public WebFormViewEngine() {
    MasterLocationFormats = new[] {
        "~/Views/{1}/{0}.master",
        "~/Views/Shared/{0}.master"
    };

    AreaMasterLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.master",
        "~/Areas/{2}/Views/Shared/{0}.master",
    };

    ViewLocationFormats = new[] {
        "~/Views/{1}/{0}.aspx",
        "~/Views/{1}/{0}.ascx",
        "~/Views/Shared/{0}.aspx",
        "~/Views/Shared/{0}.ascx"
    };

    AreaViewLocationFormats = new[] {
        "~/Areas/{2}/Views/{1}/{0}.aspx",
        "~/Areas/{2}/Views/{1}/{0}.ascx",
        "~/Areas/{2}/Views/Shared/{0}.aspx",
        "~/Areas/{2}/Views/Shared/{0}.ascx",
    };

    PartialViewLocationFormats = ViewLocationFormats;
    AreaPartialViewLocationFormats = AreaViewLocationFormats;
}

Затем необходимо очистить коллекцию ViewEngines.Engines и добавить в нее свой экземпляр ViewEngine.

0 голосов
/ 30 августа 2010

Ответ состоял в том, что MVC не смог правильно найти мой контроллер.Если MVC действительно находит ваш контроллер должным образом, VirtualPathProvider должен обработать два запроса:

  1. Первоначальный запрос с запрошенным точным URL-адресом (т.е. http: //... / Account / LogOn ).

  2. Следующая проверка FileExists для http: //.../Views/Account/LogOn.aspx, после запроса в 1. возвращает false вызывая FileExists.Это фактически возвращает содержимое aspx.

0 голосов
/ 19 августа 2010

Как уже упоминалось в SLaks, вам нужно создать пользовательский движок представлений и добавить логику поиска представлений в методе FindView.

public class CustomViewEngine : VirtualPathProviderViewEngine

{

public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)

    {
        //Set view path
        string viewPath = GetCurrentViewPath();

        //Set master path (if need be)
        string masterPath = GetCurrentMasterPath();

        return base.FindView(controllerContext, viewPath, masterPath, useCache);
    }

}

В Application_Start вы можете зарегистрировать свой движок View следующим образом:

 ViewEngines.Engines.Clear();
 ViewEngines.Engines.Add(new CustomViewEngine());
...