Использование VirtualPathProvider для загрузки представлений ASP.NET MVC из DLL - PullRequest
40 голосов
/ 26 октября 2008

Основываясь на этом вопросе здесь и используя найденный код здесь Я пытаюсь загрузить представления, которые являются встроенными ресурсами в отдельном проекте DLL, и автор оригинального вопроса говорит, что у него есть мне это удалось - но я не могу заставить его работать, так как кажется, что механизм представления MVC перехватывает запрос и все еще просматривает файловую систему для представления. Исключение:

Server Error in '/' Application.
The view 'Index' or its master could not be found. The following locations were searched:
~/Views/admin/Index.aspx
~/Views/admin/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/App/Views/admin/Index.aspx
~/App/Views/admin/Index.ascx
~/App/Views/Shared/Index.aspx
~/App/Views/Shared/Index.ascx 

Я использую CustomViewEngine, например, структуру Роба Коннери / Приложения:

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

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

             PartialViewLocationFormats = ViewLocationFormats;
         }
    }

Вот мои маршруты:

    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute("Home", "", new {controller = "Page", action = "Index", id = "Default"});
    routes.MapRoute("Default", "Page/{id}", new { controller = "Page", action = "Index", id = "" });
    routes.MapRoute("Plugins", "plugin/{controller}/{action}", new { controller = "", action = "Index", id = "" });
    routes.MapRoute("Error", "{*url}", new { controller = "Error", action = "ResourceNotFound404" });

В моем AssemblyResourceProvider я проверяю, начинается ли путь ~/plugin/, а затем, используя соглашение об имени файла dll plugin.{controller}.dll

Есть предложения?

ОБНОВЛЕНИЕ: К тому моменту, когда перенаправленный запрос, скажем, http://localhost/plugin/admin попадает в VirtualFileProvider, в конце к нему не прикрепляется никакой View. Таким образом, в методе VirtualFileProvider Open виртуальный путь ~/plugin/admin передается, когда он должен быть ~/plugin/admin/Index.aspx, как определено в моем маршруте выше. Я испортил свои маршруты или прав, ожидая, что это произойдет?

Ответы [ 2 ]

23 голосов
/ 26 октября 2008
  1. Вы должны зарегистрировать VirtualPathProvider в обработчике Global.asax Application_Start.
  2. Вы должны вызвать представление в вашей DLL, используя специальный путь, например: return View("~/Plugin/YOURDLL.dll/FULLNAME_YOUR_VIEW.aspx");

Вот статья с загружаемым примером кода, демонстрирующая это:

http://www.wynia.org/wordpress/2008/12/aspnet-mvc-plugins/

4 голосов
/ 26 октября 2008

Встроенный WebFormsViewEngine использует VirtualPathProviders, поэтому, если вы напишите VPP и зарегистрируете его, вам не нужно будет вносить какие-либо изменения в движок представления.

...