Использование VirtualPathProvider для загрузки представлений ASP.NET MVC из DLL

Исходя из этого вопроса здесь и используя найденный код здесь Я пытаясь загрузить представления, которые являются встроенными ресурсами в отдельный проект 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, например структуру Rob Connery/App, следующим образом:

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

Любые предложения?

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

Ответ 1

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

Вот статья с загружаемым образцом кода, который демонстрирует это:

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

Ответ 2

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