This article will describe exactly how to take an existing ASP.Net Web Forms site and integrate ASP.Net MVC into it.

For the sake of simplicity, I will be taking a brand new ASP.Net Web Forms project, and integrating into it.

The Web Site:

image

This is the vanilla non changed ASP.Net Web Forms project. The first thing I am going to do is search and install the NuGet package for mvcinterop.

PM> Install-Package mvcinterop

After the package is installed, add the reference to System.Web.Mvc, System.Web.Helpers, System.Web.Abstractions, System.Web.WebPages, and System.Web.Razor:

image

Next you are going to have to “hack” the project file a bit, we hope to alleviate this at some point, but for now, go ahead right click on your project and select “Unload Project”.

image

Now right click again and this time click on “Edit <project name>”.

image

This will open up the massive amount of XML for the project, luckily we only need to change one minor thing.

Prepend the “ProjectTypeGuids” with the following GUID “{E53F8FEA-EAE0-44A6-8774-FFD645390401};” it should now look like this:

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

This is adding the tooling support for ASP.Net MVC 3. Save the file.

Right click on the project again, and select “Reload Project” and click “OK” when prompted.

image

At this point we need to add some things to the web.config file to help with loading the ASP.Net MVC runtime.

Add these appSettings to your config:

<appSettings>
  <add key="ClientValidationEnabled" value="true"/>
  <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>

Change the compilation tag to include the following included assemblies:

<compilation debug="true" targetFramework="4.0">
  <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>
</compilation>

Add the following namespaces to the pages tag:

<pages>
  <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>
</pages>

Update the system.webServer to include both of these tags:

<system.webServer>
  <validation validateIntegratedModeConfiguration="false"/>
  <modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>

If you have multiple ASP.Net MVC versions installed in either your local environment, or your remote environments, be sure to also add the 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>

Save the web.config and it should now fully support ASP.Net MVC 3.

In your global.asax code behind, we need to add the default route. It is best practice to create a separate static method for this. However you will also need to add two additional using statements:

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

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Default", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );

}

An in your Application_Start add this call to that method, at this time you could also go ahead and call the area registrations:

            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);

Next lets add some default folders:

Controllers and Views:

image

This will enable the default view engine and controller factory to find your controllers.

For things to work 100% correctly, we need to add a “Default” Controller that the Web Forms pages will use.

Right click on the “Controllers” folder and click on “Add Controller” and name it “DefaultController” and click “OK”

 

image

image

For the purposes of this article, we don’t need to change anything.

We now need to setup our views folder. Right click and select “Add New Item”

image

Select a “Web Configuration File”

You will need to add a lot of boiler plate code here, but for simplicity sake, here is the config to put in the file for Razor:

<?xml version="1.0"?>

<configuration>
  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <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.webPages.razor>

  <appSettings>
    <add key="webpages:Enabled" value="false" />
  </appSettings>

  <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=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
        userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <controls>
        <add assembly="System.Web.Mvc, Version=3.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>

There are tons of articles and books on customizing this, I have simply used the default configuration with a new ASP.Net MVC 3 Razor site.

Now create a “Default” folder within the “Views” folder.

Within that new folder, Right Click and select “Add View”

image

Name it “Index” and click “Add”

image

Change the content of the new index.cshtml to the following:

@{
    ViewBag.Title = "Index";
}

<p>
    You can also find <a href="http://zeusmvc.codeplex.com/"
        title="Zeus MVC Interop Documentation">documentation on Zeus at Codeplex</a>.
</p>

 

Now that we have ASP.Net MVC 3 setup with Razor support, now we only need to render the action somewhere on our site. Open up any page’s code behind (I am going to use Default.aspx) and change the inheritance from System.Web.UI.Page to Zeus.Web.Mvc.Interop.ViewPage and in the Markup of the page. Add this somewhere:

<% Html.RenderAction("Index", "Default"); %>

And finally, run the application and navigate to the page you just modified.

Assuming you followed directions, you should now see something like this:

image

If you really want to see this project, just start a new asp.net web forms project, and follow along line by line.

Last edited Apr 12, 2011 at 8:07 AM by renevo, version 4

Comments

RenEvo Feb 18, 2013 at 5:52 AM 
Website isn't supported, only WebForms.

I may look in the future on how to work with the Website template, but you can switch a Website to a WebApplication pretty easily (right click on the project).

ajmm_gwn Jul 11, 2011 at 7:58 PM 
Any workaround for a Asp.Net Website (the one that doesn't have csproj file and is folder based) ?