Adding MVC 3 to an existing ASP.Net 4 Web Application

If you maintain an ASP.Net application for some time (as I do 😉 ), and also gained experience in developing using ASP.Net MVC, you probably want to implement any new features in MVC.

So I search for ways to add MVC to an existing ASP.Net application, and found a couple of solutions. However, they refer to older versions of MVC, so I’ll sketch here which steps are required for ASP.Net 4 and MVC 3.

The original information comes from these articles:

For some changes and additions, it’s easier if you already have an MVC project. If you do not, simply create a new “MVC3 Web Application” – all the required files will be generated.

Add assemblies

In your project, add references to the following assemblies:

  • System.Web.Abstractions
  • System.Web.Mvc
  • System.Web.Routing

Unload project and edit project

Under <ProjectTypeGuids>, add the Guid “{E53F8FEA-EAE0-44A6-8774-FFD645390401};” to get MVC-specific “Add…” items in the context menu of the Solution Explorer, such as Add Controller and Add View. The line then reads

 <ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};
    {349c5851-65df-11da-9384-00065b846f21};
    {fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

In the first <PropertyGroup>, add the line

<MvcBuildViews>true</MvcBuildViews>

Add the end of the project file, add the MVC build target:

<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

Edit web.config

Under <system.web>/<compilation>, add the following assembly references

<assemblies>
  <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</assemblies>

Under <system.web>/<pages>, add the following namespace declarations

<namespaces>
  <add namespace="System.Web.Helpers" />
  <add namespace="System.Web.Mvc" />
  <add namespace="System.Web.Mvc.Ajax" />
  <add namespace="System.Web.Mvc.Html" />
  <add namespace="System.Web.Routing" />
  <add namespace="System.Web.WebPages"/>
</namespaces>

Probably you also need to tweak assembly bindings

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
      <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Project additions

In the project, add the folders Controllers and Views, and Views/Shared.

Copy the Views/web.config file from the other MVC application.

Edit Global.asax.cs

Add these using statements:

using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

Add these lines to Application_Start():

AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

If you want to use the MVC Razor engine, also add:

ViewEngines.Engines.Add(new RazorViewEngine());

Add the methods RegisterRoutes() and RegisterGlobalFilters() as:

protected static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
  routes.MapRoute("Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }
  );
}

protected static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
  filters.Add(new HandleErrorAttribute());
}

Personally, I prefer to have each action in a separate controller class, so I use the solution presented here:

routes.MapActionRoute(
  "Default",
  "{controller}/{action}/{oid}",
  new { controller = "Default", action = "Index", oid = UrlParameter.Optional },
  new object { }
);

Start Page

If you have a defined Start Page in the ASP.Net project, you will need to redirect there from the default MVC action:

namespace MyMvcWeb.Controllers
{
  public class DefaultController : Controller
  {
    public ActionResult Index()
    {
      return Redirect(Url.Content("~/default.aspx"));
    }
  }
}

Mixing Razor and WebForms views

Razor and WebForms are two different view engines, and cannot be mixed.*

If you want to use an ASP.Net master page for a WebForms MVC view, have a look at this SO answer.

As for WebForms, the ASP.Net master page derives from System.Web.UI.MasterPage, whereas an MVC master page derives from System.Web.Mvc.ViewMasterPage (which itself also derives from System.Web.UI.MasterPage).

As for Razor, master pages have been replaced by layout views. Both views and layout views derive from System.Web.Mvc.WebViewPage<T> which has no common base class with MasterPage.

*) Note that there is a solution to using Razor views in ASP.Net masterpages (Hanselman, Hawley, Baloch), but it looks a bit hacky and fragile – and, of course, unsupported 😉

Debugging Routes

If things do not turn out as expected after implementing all these changes, have a look at the Route Debugger (original post, updated version).

4 thoughts on “Adding MVC 3 to an existing ASP.Net 4 Web Application

  1. Pingback: A jQuery Alternative for ACT CollapsiblePanelExtender | devioblog

  2. Pingback: A jQuery Alternative for ACT HoverMenuExtender | devioblog

  3. Pingback: A jQuery Alternative for ACT CalendarExtender | devioblog

  4. Pingback: Stumbling Upon the “Not Pre-Compiled” Error Message | devioblog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.