Using VirtualPathProvider to load ASP.NET MVC views from DLLs

asp.net, asp.net-mvc, virtualpathprovider

Solution

- You must register your `VirtualPathProvider` within the `Global.asax` `Application_Start` handler.

- You must call the view in your DLL using the special path like so: `return View("~/Plugin/YOURDLL.dll/FULLNAME_YOUR_VIEW.aspx");`

Here's an article with downloadable code sample that demonstrates this:

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

Problem

Based on this question here and using code found here I'm trying to load views that are embedded resources in a separate DLL project, and the original question's author says he has had success doing this - but I can't get it to work as it seems the MVC view engine is intercepting the request and still looking at the file system for the view. Exception: ``` 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 ``` I am using a `CustomViewEngine`, like Rob Connery's /App structure one as follows: ``` 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; } } ``` Here are my routes: ``` 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" }); ``` In my `AssemblyResourceProvider` I'm checking to see if the path starts `~/plugin/` and then using the dll filename convention `plugin.{controller}.dll` Any suggestions? UPDATE: By the time the routed request for say `http://localhost/plugin/admin` is getting to the VirtualFileProvider it doesn't have any View attached at the end. So in the `VirtualFileProvider`'s Open method the virtual path of `~/plugin/admin` is being passed in when it should be `~/plugin/admin/Index.aspx` as defined in my route above. Have I messed up my routes or am I right to be expecting this to happen?

Original source

Related problems