posts - 53, comments - 155, trackbacks - 4

My Links

Archives

Post Categories

Projects

Web Dev

Allowing for Dynamic Embedded View Substitution with MVC

A while back I found an interesting post on embedding resources in MVC at "The Glass is Too Big" (http://www.wynia.org/wordpress/2008/12/05/aspnet-mvc-plugins/). Following the method was straightforward and allowed views to be embedded within a Component Class Library. Well, two extra items would be nice. It would be nice to not have to write that large plug-in path, and if a view was defined in the views folder it would be returned in lieu of the embedded view.

Adding this support required two modifications. First the AssemblyResourceProvider was modified to check for the view's existence by adding a Regex pattern match and checking for the file. If the file is found within the view folder, the file is returned, if not the embedded resource will return.

 

   58             // Check to see if a file has been added to the views folder.  If so, return that view.

   59             Match m = Regex.Match(path, @"~/Plugin/[\w\.]+.dll/([\w\.]+).Views.([\w\.]+).aspx");

   60             if (m.Success)

   61             {

   62                 string assemblyMatch = m.Groups[1].Value;

   63                 string viewPath = m.Groups[2].Value;

   64                 string physicalPath = HttpContext.Current.Server.MapPath(String.Format("~/Views/{0}/{1}.aspx",

   65                     assemblyMatch, viewPath.Replace(".", "/")));

   66                 if (File.Exists(physicalPath))

   67                     return File.Open(physicalPath,FileMode.Open);

   68             }

http://www.codeplex.com/unifico/SourceControl/changeset/view/1491#9855

 

To avoid having to write out the plug-in strings I wrote an extension method to write it and return the ViewResult. Reflection is used to gather the assembly name.

 

    9     public static class ControllerPluginPathExtender

   10     {

   11         public static ViewResult PluginView(this Controller controller)

   12         {

   13             string controllerName = controller.RouteData.GetRequiredString("controller");

   14             string viewName = controller.RouteData.GetRequiredString("action");

   15             string assemblyName = controller.GetType().Assembly.FullName.Split(',')[0];

   16             string pluginPath = String.Format(

   17                     @"~/Plugin/{0}.dll/{0}.Views.{1}.{2}.aspx",

   18                     assemblyName,controllerName,viewName

   19                     );

   20             return new ViewResult{

   21                 ViewName = pluginPath

   22             };

   23         }

   24     }

http://www.codeplex.com/unifico/SourceControl/changeset/view/1491#52892

Now using the embedded option is less tedious, for example:

 

   33 

   34         [Authorize(Roles="Admin")]

   35         public ActionResult Index()

   36         {

   37             ViewData["Title"] = "Account Admin Home";

   38             ViewData["Message"] = "Welcome to the account admin";

   39 

   40             return this.PluginView();

   41             //return View("~/Plugin/App.Account.dll/App.Account.Views.Admin.Index.aspx");

   42         }

 

It would be nice to not have to use 'this', but I can't see a way around it without rebuilding MVC, not something I want to start doing. Also some caching and less reflection might be nice.



Update: The VewData and TempData have to be added to pass the models to the view

   11         public static ViewResult PluginView(this Controller controller)

   12         {

   13             string controllerName = controller.RouteData.GetRequiredString("controller");

   14             string viewName = controller.RouteData.GetRequiredString("action");

   15             string assemblyName = controller.GetType().Assembly.FullName.Split(',')[0];

   16             string pluginPath = String.Format(

   17                     @"~/Plugin/{0}.dll/{0}.Views.{1}.{2}.aspx",

   18                     assemblyName,controllerName,viewName

   19                     );

   20             return new ViewResult{

   21                 ViewName = pluginPath,

   22                 ViewData = controller.ViewData,

   23                 TempData = controller.TempData

   24             };

   25         }

Print | posted on Friday, January 02, 2009 10:18 PM | Filed Under [ Web Programming ]

kick it on DotNetKicks.com

Feedback

Gravatar

# re: Allowing for Dynamic Embedded View Substitution with MVC

Hello, thank you for the enhancements. I am using this code, but my embedded view can't seem to see Model and errors when it tries to load the type that my view inherits from. Can you post or point me towards a sample view that uses <%= Model.FieldName %> in it? Thank you, Jeremy
11/2/2009 10:54 AM | Jeremy Biros
Gravatar

# re: Allowing for Dynamic Embedded View Substitution with MVC

Did you ever solve the problem of loading models for the embedded views? I'm running into the exact same issue. Thanks!
4/14/2010 11:55 AM | Sara McCormick
Gravatar

# re: Allowing for Dynamic Embedded View Substitution with MVC

The specification must define a technique for registering EventListeners in groups. These groups will then have specified behavior in which attempts to modify the flow of an event will be restricted and affected only the group to which the EventListener in question belongs.It is also required that whatever technique is specified to accomplish this purpose be compatible with the existing DOM Level 2 Event model and any EventListeners registered using DOM Level 2 Event model methods.
4/24/2010 12:38 AM | strategie des jeux de casino
Gravatar

# re: Allowing for Dynamic Embedded View Substitution with MVC

Thanks for taking the time to discuss this, I feel strongly about information and love learning more on this. If possible, as you gain expertise, It is extremely helpful for me.
would you mind updating your blog with more information?
8/12/2010 8:17 PM | placement argent
Gravatar

# re: Allowing for Dynamic Embedded View Substitution with MVC

very nice
8/23/2010 2:14 PM | louis vuitton laptop sleeve

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 4 and 2 and type the answer here:

Powered by: