Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using VirtualPathProvider to load ASP.NET MVC views from DLLs

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?

like image 915
jmcd Avatar asked Oct 25 '08 20:10

jmcd


Video Answer


1 Answers

  1. You must register your VirtualPathProvider within the Global.asax Application_Start handler.
  2. 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/

like image 53
jmcd Avatar answered Sep 24 '22 09:09

jmcd