ASP.NET MVC 3, Razor Views, and Portable Areas

ryanzec picture ryanzec · Apr 18, 2011 · Viewed 11.1k times · Source

I am trying to using portable views with ASP.NET MVC 3 and razor views as that seems like the best way to create an easy plug-in architecture. So I have my class library setup and I have my view located in /Views/Admin/Index.cshtml and it is set as an Embedded Resource. I then include that project as a dependency for the main web application project. When I try to access the Admin controller, Index action I get a message that is can't find that view file (so the controller is being properly included). I am assume it is trying to look in the main web application project and not the portable areas binary. Is there a way to get razor views to work with portable areas?

Answer

fretje picture fretje · May 9, 2011

I have been struggling on this particular issue for a while, but I think I finally figured it out.

The folder structure and how the namespaces are called inside your project is very important for this to work properly!

I have a working example of a Portable Area with embedded razor views here:

https://github.com/fretje/MembershipStarterKit

Take a look at the structure of the project.

The area's name is UserAdministration, and there is a UserAdministrationRegistration class in the root of the project, which resides in the UserAdministration namespace. Then there's a Controllers, Models and Views folder (just like a normal MVC project) and under the Views folder, there's again a UserAdministration folder which contains the views for the area.

Also something else which is very important for the embedded views to work: you have to register a new view engine in the Application_Start method of your global.asax.cs file, did you do that?

PortableAreaRegistration.RegisterEmbeddedViewEngine();

And... In your registration class, make sure you override the RegisterArea method which takes 2 parameters (AreaRegistrationContext context and IApplicationBus bus), and call the base implementation in there:

public override void RegisterArea(AreaRegistrationContext context, 
    IApplicationBus bus)
{
    base.RegisterArea(context, bus); // <== very important!

    context.MapRoute(
        "UserAdministration", 
        AreaName + "/{controller}/{action}/{id}",
        new { controller = "UserAdministration", action = "Index", 
              id = UrlParameter.Optional }
    );
}

If you don't call the base implementation, you have to at least add a

RegisterAreaEmbeddedResources();

To make sure that your embedded views and resources are registered.