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

11.1k views Asked by At

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?

3

There are 3 answers

1
DevMania On

Did you make sure that you Marked your View as Embedded Resource in your Portable Area?

Also i found that nice feature of portable areas is that you can override the embedded Views, so if you Place a View in your Host App with Same name and Location of the Embedded one with Different Code Logic it will take priority over the Embedded one Nice !!!

Hope this Helps

3
fretje On

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.

2
Pieter On

I got this working by following the instructions in Fretje's answer and then also add a nuget package reference to EmbeddedResourceVirtualPathProvider in your website.