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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

  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/

Method 2

The built-in WebFormsViewEngine uses VirtualPathProviders, so if you write a VPP and register it, you won’t need to make any changes to the view engine.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x