views:

346

answers:

3

I used the code below so far with ASP.NET MVC v1 and v2 but when I added an Area today to my application, the controller for the area couldn't find any views in my Areas/Views/controllerView folder. It issued the very well known exception that it searched those 4 standard folders but it did not look under Areas..

How can I change the code so that it will work with Areas? Maybe an example of custom view engine under ASP.NET MVC 2 with Areas support? The information about it on the net is very scarse..

Here's the code:

public class PendingViewEngine : VirtualPathProviderViewEngine
{
    public PendingViewEngine()
    {
        // This is where we tell MVC where to look for our files. 
        /* {0} = view name or master page name       
         * {1} = controller name      */
        MasterLocationFormats = new[] {"~/Views/Shared/{0}.master", "~/Views/{0}.master"};
        ViewLocationFormats = new[]
                                {
                                    "~/Views/{1}/{0}.aspx", "~/Views/Shared/{0}.aspx", "~/Views/Shared/{0}.ascx",
                                    "~/Views/{1}/{0}.ascx"
                                };
        PartialViewLocationFormats = new[] {"~/Views/{1}/{0}.ascx", "~/Views/Shared/{0}.ascx"};
    }

    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        return new WebFormView(partialPath, "");
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        return new WebFormView(viewPath, masterPath);
    }
}
A: 

When you created an Area, did it create the AreaRegistration class? If so, do you have this in your global.asax.cs? As the name implies, it registers the areas with MVC.

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
    }
Jab
I do have this and I have the area registration class but the problem remains. The problem is, my view engine resets some paths to folders to allow linking between views in their respective folders and the Shared folder, as you can see.
mare
Jab
Thanks for your suggestions but it must be a view engine problem because if I comment it out from global.asax.cs, it finds the area views without a problem.
mare
Can you try changing `return new WebFormView(partialPath, "");` to `return new WebFormView(partialPath, null);`?
Jab
no difference..
mare
+1  A: 

... searched those 4 standard folders but it did not look under Areas

This is actually a hint - MVC does not know where and how to look for the Area Views since the locations have not been defined in your custom view engine.

You may need to possibly setup the AreaPartialViewLocationFormats and include the Areas Location in the ViewLocationFomats property since this is an area enabled application.

ViewLocationFormats = new[]
{
   "~/Areas/Views/{1}/{0}.aspx",
   ...
};

And possibly...

AreaPartialViewLocationFormats = new[]
{
    "~/Areas/{1}/Views/{0}.ascx",
    "~/Areas/Views/{1}/{0}.ascx",
    "~/Views/Shared/{0}.ascx"
};

Two references:

  1. MSDN <- Probably updated since MVC1 to include the new Areas stuff, thus why its not working
  2. The Haack <- Old post but a good intro and overview
Ahmad
A: 

Not a direct response to your question, but something other readers might find useful, to use the custom viewengine the global.asax needs to be modified:

 void Application_Start(object sender, EventArgs e)
 {
  RegisterRoutes(RouteTable.Routes);
  ViewEngines.Engines.Clear();
  ViewEngines.Engines.Add(new PendingViewEngine());
 } 
  • Matt
MJBarlow