Escolar Documentos
Profissional Documentos
Cultura Documentos
NET MVC
Ever since Microsoft started working on the ASP.NET MVC framework, one of the primary concerns was
the framework's ability to re-use as many features as possible from ASP.NET Webforms. In this article
by Maarten Balliauw, we will see how we can mix ASP.NET Webforms and ASP.NET MVC in one
application and how data is shared between both these technologies.
Not every ASP.NET MVC web application will be built from scratch. Several projects will probably end up migrating
from classic ASP.NET to ASP.NET MVC. The question of how to combine both technologies in one application arises—is
it possible to combine both ASP.NET Webforms and ASP.NET MVC in one web application? Luckily, the answer is yes.
Combining ASP.NET Webforms and ASP.NET MVC in one application is possible—in fact, it is quite easy. The reason
for this is that the ASP.NET MVC framework has been built on top of ASP.NET. There's actually only one crucial
difference: ASP.NET lives in System.Web, whereas ASP.NET MVC lives in System.Web, System.Web.Routing,
System.Web.Abstractions, and System.Web.Mvc. This means that adding these assemblies as a reference in an
existing ASP.NET application should give you a good start on combining the two technologies.
Another advantage of the fact that ASP.NET MVC is built on top of ASP.NET is that data can be easily shared between
both of these technologies. For example, the Session state object is available in both the technologies, effectively
enabling data to be shared via the Session state.
System.Web.Abstractions
System.Web.Mvc
After adding these assembly references, the ASP.NET MVC folder structure should be created. Because the ASP.NET
MVC framework is based on some conventions (for example, controllers are located in Controllers), these
conventions should be respected. Add the folder Controllers, Views, and Views | Shared to your existing ASP.NET
application.
The next step in enabling ASP.NET MVC in an ASP.NET Webforms application is to update the web.config file, with the
following code:
< ?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="false">
<assemblies>
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Abstractions,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Web.Routing,
Version=3.5.0.0, Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<pages>
<namespaces>
<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.Linq"/>
<add namespace="System.Collections.Generic"/>
</namespaces>
</pages>
<httpModules>
<add name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web.Routing, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
</system.web>
</configuration>
Note that your existing ASP.NET Webforms web.config should not be replaced by the above web.config! The
configured sections should be inserted into an existing web.config file in order to enable ASP.NET MVC.
There's one thing left to do: configure routing. This can easily be done by adding the default ASP.NET MVC's global
application class contents into an existing (or new) global application class, Global.asax.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MixingBothWorldsExample
{
public class Global : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapRoute(
"Default",
// Route name
"{controller}/{action}/{id}",
// URL with parameters
new { controller = "Home", action = "Index", id = "" }
// Parameter defaults
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}
This code registers a default ASP.NET MVC route, which will map any URL of the form /Controller/Action/Idinto a
controller instance and action method. There's one difference with an ASP.NET MVC application that needs to be
noted—a catch-all route is defined in order to prevent a request for ASP.NET Webforms to be routed into ASP.NET
MVC. This catch-all route looks like this:
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
This is basically triggered on every request ending in .aspx. It tells the routing engine to ignore this request and leave
it to ASP.NET Webforms to handle things.
With the ASP.NET MVC assemblies referenced, the folder structure created, and the necessary configurations in place,
we can now start adding controllers and views. Add a new controller in the Controllers folder, for example, the
following simpleHomeController:
using System.Web.Mvc;
namespace MixingBothWorldsExample.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "This is ASP.NET MVC!";
return View();
}
}
}
The above controller will simply render a view, and pass it a message through the ViewData dictionary. This view,
located in Views | Home | Index.aspx, would look like this:
<%@ Page Language="C#"
AutoEventWireup="true"
CodeBehind="Index.aspx.cs"
Inherits="MixingBothWorldsExample.Views.Home.Index" %>
1. HttpContext
2. Session
3. Server
4. Request
5. Response
6. Cookies
This way, it is easy to set a Session state item in classic ASP.NET Webforms and read it in ASP.NET MVC.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MixingBothWorldsExample
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Session["SharedData"] = "This message is set by classic
ASP.NET.";
}
}
}
The above code is a "codebehind" for a classic ASP.NET page. As you can see, it sets the SharedData dictionary item
of Session to a string value. This data can easily be read easily in an ASP.NET MVC controller, for example:
using System.Web.Mvc;
namespace MixingBothWorldsExample.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "This is ASP.NET MVC!";
ViewData["SharedData"] = Session["SharedData"] ?? "";
return View();
}
}
}
The Index action method tries to read data from the SharedData dictionary item of Session. If it has been set by
ASP.NET Webforms or ASP.NET MVC, it is assigned to the ViewData dictionary. In other cases, an empty string is
passed in.
1. Open the project file in a text editor. For example, start Notepad and open the project file for your ASP.NET
MVC application (that is, MyMvcApplication.csproj).
2. Find the top-most <PropertyGroup> element and add a new element named <MvcBuildViews>:
<MvcBuildViews>:
<PropertyGroup>
...
<MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
3. Scroll down to the end of the file and uncomment the <Target Name="AfterBuild"> element. Update its
contents to match the following:
<Target Name="AfterBuild"
Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp"
PhysicalPath="$(ProjectDir)..$(ProjectName)"/>
</Target>
4. Save the file and reload the project in Visual Studio.
Enabling view compilation may add some extra time to the build process. It is recommended that this
is not enabled during development as a lot of compilation is typically involved during the development
process.
Summary
In this article, we mixed ASP.NET Webforms and ASP.NET MVC in one application and shared data between both
these technologies. We also added a post-build action to a project file to make sure that all views can be compiled.