Integrating ASP.NET MVC 3 into existing upgraded ASP.NET 4 Web Forms applications
I got an interesting question recently from a gentleman who has an existing ASP.NET WebForms 2.0 application that works just fine. He's upgraded it to ASP.NET 4 and it still works great, but now he wants to add some ASP.NET MVC pages to it. He doesn't want to rewrite the application.
A few years ago I did a post on "Hybrid" ASP.NET applications. The goal was to reinforce the point that you can have ASP.NET applications that are both WebForms and MVC (as well as WCF and ASMX Web Services and on and on.) While the File|New Project dialog gives you a choice between This and That, in fact it's all ASP.NET underneath. You are welcome to mix and match "cafeteria style" and create apps in any combination you'd like.
The easiest way to add ASP.NET MVC 3 to an upgraded ASP.NET 2.0 WebForms application:
- Run the Upgrade Wizard (open the Visual Studio2008 Web Application in Visual Studio 2010)
- Create a default ASP.NET MVC application for reference (you'll throw it away later)
- Use a differencing tool like Beyond Compare to integrate the new web.config entries from the ASP.NET MVC sections into the upgraded ASP.NET WebForms application
- Dance
Here's the longer more detailed version of the above.
Upgrading an ASP.NET 2.0 WebForms Application
I've created a simple Visual Studio 2008 ASP.NET WebForms Application running under .NET 2. It's a simple calculator.
It works nicely. Now, open this application in Visual Studio 2010. You'll get the Conversion/Upgrade Wizard.
Next, Next, Yada, Yada, Yada, Finish. You'll get an prompt to upgrade the 2.0 application to .NET Framework 4. Click Yes.
Here's the same WebForms application, now upgraded in Visual Studio 2010. It still runs and it's still WebForms. Or, more accurately, it continues to be ASP.NET.
I'm going to take a new default ASP.NET MVC 3 application and Beyond Compare and compare the upgraded app with the default app.
I'll copy over these folders and files:
- Content
- Controllers
- Models
- Scripts
- Views
- Global.asax, Global.asax.cs
Now, here's the before and after references from the upgraded application. The old on the left and the new on the right.
Here's the references I added.
- Microsoft.CSharp
- (as this was a C# app)
- System.Web.Mvc
- From \Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies
- System.Web.WebPages and System.Web.Razor
- From \Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies
- System.ComponentModel.DataAnnotations
Next, add these sections to the Web.config. Again, it's easier to use a diff tool and you might have a little trial and error.
Thought: This might be a nice NuGet package for someone to make...
Add these settings in appSettings:
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
Add these assembly elements under compilation:
<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 these namespaces in pages:
<system.web>
<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>
</system.web>
If you're running IIS7 at some point, which I'm sure you will, add these:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
And finally add this assembly binding redirect, just in case you've got ASP.NET MVC 1 or 2 assemblies in your Global Assembly Cache (GAC).
<configuration>
<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>
</configuration>
Also, make sure you merge in the Global.asax.cs so that your Routes are registered at application startup.
public class SomeHybrid: System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
Now, at this point I can visit both pages. The WebForms page is a file on disk, so ASP.NET routing passes requests directly on to this page when I /default.aspx. The ASP.NET Routing engine is engaged so I can also hit /Home/Index.
If I want to get fancy, I can add a PageRoute so I have pretty URLs when visit my WebForms pages as well. Just add a route in the Global.asax like this. Make sure that simple routes like these come first, as the default ASP.NET MVC route is very "greedy" and would gobble up a simple URL like /calculator
routes.MapPageRoute("WebFormThing", "Calculator", "~/Default.aspx");
Now I can visit /Calculator and the request is routed to /Default.aspx. And of course, my ASP.NET MVC 3 Razor pages like /Home/Index work also.
Finally, just to make the point, here's the Default.aspx from the WebForms part of my new app next to the source for a Razor page.
You CAN have it all, Dear Reader. Enjoy.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Can you comment/ add recommendations ?
William - Yes, but you can take over that route, no?
Robert - I'll blog a solution that lets you mix and match master pages soon.
If I am running this hybird app in Azure, would I need the 2 lines of <system.webServer> settings that you have here for IIS7?
Thanks,
Ray.
I'm getting an issue with loading the copied over Global.asax file. The MVC app was called MV3Application and this is still in the asax file. The error is then:
Source Error:
Line 1: <%@ Application Codebehind="Global.asax.cs" Inherits="MVC3Application.MvcApplication" Language="C#" %>
I'm a newbie .NET developer. Have I missed a step?
I am a very, very, newbie to all kind about how to program in any way what ever. So what more about I have to say only nothing else to explain like this. Before I have to say to you sorry about my bad spelling english because my origin language is German or Dutch. My question to you are now reading this is:
If anyone knows a way to teach a newbie like me the knowledge I would like to have please give me a hug and do give me good information where to learn what I have to know about the needs for what my project is.
More about my project: You will find at my homepage.
Thank you for your time and participation to read this newbie question.
And thank you for review my project at my homepage I am very waiting for your feedback.
My homepage is in the language English, Dutch and German.
P.S.
Aditional information about project:
My idea is to merge existing systems in the daily money market with a new vision how to participate in the daily average of costs about consumer spendings for all kind of products. The target is to start this system with low amount charges to reinvest in this daily consumer spendings. The profit is a win, win, situation for companies and consumers who participate in this system,
©The system is based on the back office network for POS machines who uses this back office network system.®
My Published Email:viewunity@india.org in this session is only a autorespond account and if you mail me you will get more information about my project.
To the Admin of this session: I would be not wondering if you delete this message but I would like to ask you if you do please forward this information to anyone who could bring me more along the way I will like to go.
The first question at the time Microsoft Windows was launched was ''Where Do You Go Today''
Sometimes I think people forget this quest.
Kind Regard Viewunity Bonnen.
thanks Scott
@Viewunity Bonen www.asp.net
Am I correct? Or the WebForms will be replaced by MVC at all?
Waiting for the Master page solution (solution that lets you mix and match master pages) !!!!!!!!!!.
Cheers
did you ever get around to that blog on mixed master pages? and just to throw another ball in the air how about with Spring.Net in the mix and it's master page implementation! :0)
Cheers,
Griff
I have an existing ASP.NET application in VB.Net and could add ASP.NET MVC pages to it.
Is it possible to add ASP.NET MVC parts written in C# to this existing VB.net application?
Many thanks
I wonder why choose this approach rather than at least two web projects which share session?
I've trying to decide between the approach you listed here, or a solutions with two web projects that share session state (and then shared code projects for common classes or services between the two). I'm guessing there would be some cost associated with the two separate web projects such as some more IIS configuration using two web apps and possibly more duplicated code. But other than that I'm leaning towards the 2 project approach since I believe the hybrid would be more difficult to maintain after transitioning all pages and controls to MVC --- because it would be an effort to detangle.
What do you think?
Thank,
John
-John
- no mvc context items (such as 'add view' when you right click a controller action)
- mvc scaffolding does not work with it (it complains about the project type not being mvc)
- if you rely on 3rd party controls (such as telerik radupload for example) you might find they break once you introduce mvc
-no razor intellisense
maybe there are workarounds, but i started to get nervous about investing too much time into something that might bite me further down the line.
Thanks for the info Scott.
porting an app from aspx to mvc
have a set of deep directories which have both content files (images) and html, served via default.aspx in each folder.
I want to keep the images in their original paths, so i copied over the whole dir. But I can't find a way to route things so that content is served up at the same url as the default.aspx woudl have been, ie site.com/path/ ... since this path exists, the route never fires.
any ideas....?
In the end I went with this:
routes.Ignore("{*allaxd}", new { allaxd = @".*\.axd(/.*)?" });
This allowed the Microsoft Charting controls to function requesting axd files at any path on the site.
Scott, I think this would be pretty common and could be worth updating your code in the post to handle this.
Hi Scott,
As per your article I follow the steps to integrate WebApp with MVC application. I am successfully integrated MVC project into WebApp(C#).
The problem is If I choose WebApp as VB.NET project, and integrated with MVC project. In this case the request is not routing to corresponding MVC files.
What could be the reason not routing to MVC. Do we need to plug some extra dlls?
Thanks
Gopal
I upgraded my aspx webforms web application from 3.5 to 4.0 and did the changes to support MVC. I did the above mentioned steps. But the thing is when i try to add new item, I dont get MVC3 Razor page in add new item dialog. I have installed MVC3. Also I am not able to add reference to System.Web.Razor as the dll is not coming up in .Net references.
Kindly give me your suggestions.
Am i missing on something?
Thanks and Regards,
Gangadharan
Comments are closed.