In this 'how to' I will demonstrate how to integrate an ASP.NET MVC 2 project to an ASP.NET WebForms application that already exists. There are many weird ungoogleable issues and extra tips that haven't been covered elsewhere. I hope this guide helps you get started.
Update: I have written an updated blog post for the slightly different details of
adding to a web forms project with an ASP.NET MVC 3 project.
1. Add references
Right click on your web root project in Visual Studio (2010 in my case) and add the following references:
- System.Web.Routing
- System.Web.Abstractions
- System.Web.Mvc
2. Configuration
Make your web.config look like this. Obviously not exactly like this, don't just paste this over the top of your glorious web.config. I'm just highlighting the necessary points that need to be fitted into your existing web.config:
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add assembly="System.Web.Abstractions,Version=4.0.0.0, Culture=neutral,PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing,Version=4.0.0.0, Culture=neutral,PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
<namespaces>
<add namespace="System.Web.Mvc"/>
<add namespace="System.Web.Mvc.Ajax"/>
<add namespace="System.Web.Mvc.Html"/>
<add namespace="System.Web.Routing"/>
</namespaces>
</pages>
</system.web>
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Update: I have changed my recommendation against using <modules runAllManagedModulesForAllRequests="true">
in favour of adding the UrlRoutingModule-4.0 module with a blank precondition as I explain in my article Don't use runAllManagedModulesForAllRequests="true" for MVC routing.
3. Routing
You will need to add a global.asax file to your web application if you haven't already got one. Right click > Add > Add New Item > Global Application Class:
Now in your global.asax add these usings:
using System.Web.Mvc;
using System.Web.Routing;
Now add these lines:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//ignore aspx pages (web forms take care of these)
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapRoute(
// Route name
"Default",
// URL with parameters
"{controller}/{action}/{id}",
// Parameter defaults
new { controller = "home", action = "index", id = "" }
);
}
protected void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
4. Add some standard folders to the solution
Add a folder named 'Controllers' to your web project.
Add a folder named 'Views' to your web project.
Add a folder named 'Shared' to that Views folder.
Add a web configuration file to the Views folder (web.config).
Open this web.config in the Views folder and ensure make its contents as follows:
<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>
5. Get Visual Studio 2010 to recognise your MVC skills
If you right click the Controllers folder and select Add, you'll notice there is no Controller class to add. You need to make a change to your web project file.
Using Windows Explorer find the web project file (Web.csproj in my case) and open it in a text editor. You will need to add "{F85E285D-A4E0-4152-9332-AB1D724D3325};" to the ProjectTypeGuids element.
E.g. mine now looks like this:
<ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
6. Optional: Add a Controller (for a laugh)
Back to Visual Studio 2010 and right click the Controllers folder > Add > Controller... call it HomeController.
using System.Web.Mvc;
namespace Web.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "This is MVC";
return View();
}
}
}
7. Optional: Add a View (just to show off)
Right click where it says
return View();
and select Add View... then click Add.
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
</head>
<body>
<div>
<%: ViewData["Message"] %>
</div>
</body>
</html>
8. Optional: Try it (just to self-indulge your skills)
Now run you site and go to http://{localhost}/home
I hope this saved you the hours it took me! Please comment if you have any feedback. It would be much appreciated
More reading here if you would like to
use an existing WebForms MasterPage in your new MVC project.