天天看點

ASP.NET WebForms and MVC together in one project

ASP.NET WebForms and MVC together in one project

http://blogs.taiga.nl/martijn/2009/06/03/aspnet-webforms-and-mvc-together-in-one-project/

This post briefly describes a solution to mix ASP.NET WebForms and MVC in one project. You can download a sample project that might be more useful than my ramblings. Download the sample here , unzip, open with VS 2008 SP1 and hit F5.

There are lots of ‘legacy’ ASP.NET WebForms applications out there in the wild. What if you want to create new functionality or rebuild an existing part with ASP.NET MVC, but you can’t (or won’t) create a separate new project?

The simple solution is to add the default MVC folders (Content, Controlllers, Scripts, Views etc.) to the root of the web project, add references to the MVC binaries, modify web.config and add the MVC GUID to the ProjectTypeGuids in the project file. A major drawback however is that it pollutes the root of your carefully structured application. This post will show you how you can logically separate the new MVC pieces from the existing WebForms app in a single project.

Isolate the MVC bits

ASP.NET WebForms and MVC together in one project

  A simple requirement: I want that all my MVC folders reside in the folder /MyMvcApp and I also want that all urls of the MVC app start with /mymvcapp. No interference with my old WebForms app please.

Area’s

About a year ago, Phil Haacked showed a concept called area’s to partition an ASP.NET MVC application. After that, Steve Sanderson came up with an improved version of the concept.

Although designed to partition an MVC application, area’s are also useful when we want to isolate our MVC application from our existing WebForms app. The solution from Steve Sanderson almost completely fits our needs, follow the link for more technical details. The only thing I removed was the usage of an Areas subfolder in the project where all the individual MVC sub-applications. Simply didn’t need the extra subfolder and url of the MVC app is closer to the physical structure.

So, I implemented area’s with a specific AreaViewEngine that can lookup views based on the area name and added the extension to the RouteCollection class to add area information when mapping routes. This is how Global.asax.cs looks:

protected

 void

 Application_Start(object

 sender, EventArgs e)      
{      
ViewEngines.Engines.Clear();      
ViewEngines.Engines.Add(new

 AreaViewEngine());      
RegisterRoutes(RouteTable.Routes);      
}      
public

 static

 void

 RegisterRoutes(RouteCollection routes)      
{      
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"

);      
routes.IgnoreRoute("{*favicon}"

, new

 { favicon = @"(.*/)?favicon.ico(/.*)?"

 });      
routes.CreateArea("mymvcapp"

, "WebFormsMVCDemo.MyMvcApp.Controllers"

,      
routes.MapRoute("mymvcapp-defaultroute"

, "mymvcapp/{controller}/{action}/{id}"

, new

 { action = "Index"

, controller = "Home"

, id = ""

 })      
);      
}      

With the ViewEngine and routes in place, we’re able to run the MVC app from the url /mymvcapp. To make sure the WebForms url’s still work, we just have to add some ignore statements in Global.asax.cs (in our case, exclude .aspx and .ashx from routing):

public

 static

 void

 RegisterRoutes(RouteCollection routes)      
{      
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"

);      
routes.IgnoreRoute("{*allaspx}"

, new

 { allaspx = @".*/.aspx(/.*)?"

 });      
routes.IgnoreRoute("{*allashx}"

, new

 { allashx = @".*/.ashx(/.*)?"

 });      
routes.IgnoreRoute("{*favicon}"

, new

 { favicon = @"(.*/)?favicon.ico(/.*)?"

 });      
routes.CreateArea("mymvcapp"

, "WebFormsMVCDemo.MyMvcApp.Controllers"

,      
routes.MapRoute("mymvcapp-defaultroute"

, "mymvcapp/{controller}/{action}/{id}"

, new

 { action = "Index"

, controller = "Home"

, id = ""

 })      
);      
}      

One caveat: when performing the request for /mymvcapp without controller name (and action), the Default.aspx that comes with the MVC projects was loaded, but area’s seem so cause a problem with the default one. Instead of rewriting the url from ‘default.aspx’ to ‘/’, I had to rewrite to url to ‘Home/Index’:

public

 partial

 class

 _Default : Page      
{      
public

 void

 Page_Load(object

 sender, System.EventArgs e)      
{      
string

 pathToRewriteTo = Request.Path.ToLowerInvariant().Replace("default.aspx"

, "Home/Index"

);      
HttpContext.Current.RewritePath(pathToRewriteTo, false

);      
IHttpHandler httpHandler = new

 MvcHttpHandler();      
httpHandler.ProcessRequest(HttpContext.Current);      
}      
}      

I’m under the impression that I’m missing something very simple, but couldn’t get my fingers behind it, so if you know it, please comment.

That’s it. I created a sample project with both WebForms and an MVC app in a subfolder. You can download it here .

Tagged: Area , ASP.NET MVC , Sample , WebForms

Getting Visual Studio to Offer MVC Items

There is actually one difference between a native MVC web application project and your

“upgraded” WebForms project. When you want to add a view template using the Add äNew

Item dialog, Visual Studio won’t offer you an MVC View Page or any of the other MVC-specific

items. And when you right-click inside an action method, you don’t get the option to add a

view. That’s because Visual Studio doesn’t realize you’ve got an ASP.NET MVC project. This is

why, in step 3 previously (when adding a view for HomeController’s Index action), you had to

use a WebForms page and change its base class manually.

To resolve this, you need to add a project type hint for Visual Studio.

nCaution Before you proceed, back up your project file (i.e., the one with the .csproj extension), or at

least be sure it’s up to date in your source control system. If you edit the project file incorrectly, Visual Studio

will become unable to open it.

1. In Solution Explorer, right-click your project name and choose Unload Project.

2. Right-click the project name again, and choose Edit MyProject.csproj (or whatever

your project is called).

3. You’ll now see the .csproj XML file. Find the <ProjectTypeGuids> node, which contains

a semicolon-separated series of GUIDs, and add the following value in front of

the others:

{603c0e0b-db56-11dc-be95-000d561079b0};

568 CHAPTER 16 n COMBINING MVC AND WEBFORMS

Do not add any extra spaces or line breaks. If you don’t want to type in the GUID by

hand, you can copy and paste it from the corresponding section of any genuine

ASP.NET MVC .csproj file you might have elsewhere.

4. Save the updated .csproj file. Then reload the project by right-clicking its name in

Solution Explorer and choosing Reload Project.

If you get the error “This project type is not supported by this installation,” then either

you have mistyped the GUID, or you haven’t installed the MVC Framework on your PC.

If you get the error “Unable to read the project file,” then simply click OK and choose

Reload Project again. It seems to sort itself out, for whatever reason.

You should now find that MVC-specific items appear in the Add äNew Item dialog,

alongside the usual WebForms items, and you’ll be able to right-click inside an action method

and choose Add View.

繼續閱讀