ASP.NET MVC Areas in separate projects/assemblies

Had to implement a webshop section for an ASP.NET MVC website project which was to be reused by another one. Solving it was a bit finicky, so documenting it roughly here in case I need to do it again in the future. Not sure I remember all the steps, but hopefully it’ll be enough to reproduce the effect:P

The main problem here is the way razor views are compiled run-time and that is solved by using the Razor Generator VS extension to pre-compile the views and the belonging RazorGenerator.Mvc Nuget package to enable the web application to find them during run-time.

Don’t know if the solution I ended up with is the best, but it worked fairly great. If you have better/cleaner solutions please leave a comment 🙂

The separate project

Project-view

  1. Install the Visual Studio extension named Razor Generator.
    This will be used as custom tool for views to pre-compile them.

  2. Install the RazorGenerator.Mvc Nuget package in your project which among other things will add a RazorGeneratorMvcStart class which sets up your web application to use the mentioned pre-compiled views.
    PM> Install-Package RazorGenerator.Mvc -ProjectName MySeparateProject
  3. Add a copy of a basic app.config and Web.config to the project.
    I got these from a new MVC 5 project to make sure they were clean and basic. Might be skipped, but think the razor view editor might have issues without them.

  4. Create your area as you normally would if it was in the same project as the actual web application, with one exception:
  5. For all views you create, the file needs to begin with @* Generator: MvcView *@ and for its properties the Custom Tool must be set to RazorGenerator.
    When this is done, whenever you save the view file (or manually right-click, Run Custom Tool) you will get a file called ViewFile.generated.cs which is the pre-compiled version of your view.

You can see the in the screenshot to the right how I structured my project. If you’re not sure what you need to make an area, you can do what I did: Create a new clean web application project, add an area to it, and move everything from ~/Areas/MyArea over into the separate project.

The ASP.NET Web Application project(s)

  1. Add your separate project as a reference in your web application project.

Not kidding, that’s all you need to do. Although if you try it out, it might look rather boring because areas doesn’t use the web application layout by default. Add a layout to your area, or just make the _ViewStart.cshtml global, which is what I did, to fix that 🙂

Challenges/Troubleshooting

  • Since the views are pre-compiled, you won’t be able to edit the views while the web application is running and just refresh in your browser. You need to stop the session, do the changes, recompile everything and start the session again. If you’re developing a new area, it might be a good idea to develop it as part of the web application first and move it out into a shared project when it’s done or close to done.
  • Sometimes if you forget and edit views while Visual Studio is in a running debug session, or if you try to rename a view, you might end up with duplicate generated view classes. For example Index.generated.cs and Index1.generated.cs. When this happens you need to delete both files, open up your csproj file and look for an XML element called lastGenOutput with value Index1.generated.cs, change it back to Index.generated.cs, reload your project and Run Custom Tool for the cshtml file (or just re-save it). It’s an annoying bug/feature of the T4 templating engine in Visual Studio or something…
  • For scripts and stylesheets specific to the area, there is probably a good solution using bundling somehow, which I wasn’t able to get into at this moment. In my case the amount of javascript and css was so small that I decided to compile them into my assembly as embedded resources and then just embed them right into my views with a simple extention method.