Jim Geurts asked an interesting question in a comment to one of my other MVC posts (paraphrased): How do classic ASP.NET web forms coexist with the new ASP.NET Extensions MVC Framework?

At this time, with the bits I'm privy to, they work very well.

Setting the Stage

I'm going to use what I hope is a common scenario as an example and demonstrate how you might use both frameworks to accomplish a given task.  Let's say you had an existing web site built using the ASP.NET 2.0 Web Application Project type in VS2005 and you recently upgraded it to a VS2008 solution web project and you are building it against .NET 3.5. Ok, nothing exciting here, but now you want to start adding some new pages using MVC.  Let's say you have a basic 'Product Management' application that you've built for your marketing department to control how products are described and priced on your storefront app. You have a Login.aspx page and you have some ProductEdit.aspx-like pages.  Let's say you want to replace the ProductEdit.aspx page with an MVC page, but leave all the login/logoff stuff alone for now.

Let's assume that your Login.aspx page set a Forms Auth session cookie like normal. For the purpose of this demo, we're going to use something very simple, clear, but ordinarily WRONG. I'm going to set a session variable called "LoggedIn" = true. This is only to SIMULATE a forms auth scenario, because I don't want to clutter this blog post up with a lot of forms auth stuff. That's another post :)

So let's say your Login.aspx's codebehind has a method like this:

public void loginButton_Click(object sender, EventArgs args)
{
    //TODO: Actual authentication here 
    //      with proper forms auth cookies and such
    Session["LoggedIn"] = true;

}

Gearing up for MVC

First, add a reference to the the assembly that contains the MVC bits. At this time, with the preview that I have, it's System.Web.Extensions v3.6.0.0, but it'll probably be different by Beta/CTP/RTM. If you already had ASP.NET AJAX stuff loaded with a reference to System.Web.Extensions, you'll need to un-reference that first and then add this reference.

Next, you'll need to edit your script mappings in IIS to allow a * mapping to the aspnet_isapi.dll. Examine the script mapping settings in IIS for the .aspx file extention and duplicate everything, but for * instead of .aspx.  If you need help with this configuration, let me know. I'd rather not bog down this blog post with that kind of minutiae. I can do another post on that if it becomes necessary.

If you don't already have a Global.asax defined, the next thing you'll need to do is r-click on your ASP.NET web app project and choose 'Add New Item...', and then choose 'Global Application Class'.

In your Application_Start method, you'll need to add some MVC routing information. To get started, you can use the basic REST URL pattern common among many MVC-type frameworks. So your code will look something like this:

using System.Web.Mvc;
...
protected void Application_Start(object sender, EventArgs e)
{
    RouteTable.Routes.Add(new Route
    {
        Url = "[controller]/[action]/[id]",
        Defaults = new { action = "Index", id = (string)null },
        RouteHandler = typeof(MvcRouteHandler)
    });
}

This means that when you request a URL like /Products/Edit/9 (NOTE: NO .ASPX on the end! Very important!), the MVC framework will route your request to the ProductsController and call the Edit(int id) action method and pass 9 as the id parameter.

Creating a Controller and a View

  1. Create two folders in your ASP.NET project: Controllers and Views.  Under Views, create a folder called 'Products' (for example, or whatever the 'XYZ' in your XYZController is, so FooController will look in Views/Foo for its views).
  2. R-click on the 'Products' folder under 'Views', 'Add New Item', under the 'Web' section, choose 'MVC View Page'. Name it 'Edit.aspx'.
  3. R-click on the 'Controllers' folder, 'Add new item', 'web' section, choose 'MVC Controller Class', name it 'ProductsController.cs'

Your folder structure should now look something like this (assuming Login.aspx and Default.aspx were already there, plus whatever other files you may have):

At this point, you should be able to compile at least.

Adding the Edit Action to Your Controller

Visual Studio probably created an 'Index()' action in your controller by default. Rename 'Index()' to 'Edit(int productID)'.  I'm not going to get into all the whys and hows of how MVC form handling and such. That's another  blog post. I'm only concentrating here on showing how co-existence between the two ASP.NET frameworks can work. So, in that vein, here is an Edit() action method which demonstrates a few things. Here's the code, we'll talk about it below:

[ControllerAction]
public void Edit(int id)
{
    IHttpSessionState session = HttpContext.Session;

    if (session["LoggedIn"] == null || ((bool)session["LoggedIn"] != true))
        RenderView("NotLoggedIn");

    Product p = SomeFancyDataAccess.GetProductByID(id);

    RenderView("Edit", p);
}

 

As you can see here, there are a few things going on. Again, this isn't to illustrate good MVC coding practices, only co-existence.  You can see that we have access to the ASP.NET session state and can read values. There are ways of reading role information and making declarative authorization statements (using attributes or code, etc).  For right now, I want to show how you can read information from classic ASP.NET WebForms pages and interact with them.

The rest of that code ends up doing what controller actions do (set up the view and fire it off). The Edit.aspx page then gets fired with its ViewData property set to be the Product with ID 9.

Conclusion

I realize I kinda zipped through some of the MVC stuff. I really wanted to stay focused on just demonstrating co-existence. We can get into how MVC works later. For right now, this is all you need to sprinkle in some MVC into the middle of an established ASP.NET WebForms Project.

kick it on DotNetKicks.com

 

Technorati Tags: ,