Mixing ASP.NET Webforms and ASP.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.
(For more resources on .NET, see here.)
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.
An ASP.NET Webforms application can become ASP.NET MVC enabled by following some simple steps. First of all, add a reference to the following three assemblies to your existing ASP.NET application:
- System.Web.Routing
- 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" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title></title>
</head>
<body>
<div>
<h1><%=Html.Encode(ViewData["Message"]) %></h1>
</div>
</body>
</html>
The above view renders a simple HTML page and renders the ViewData dictionary's message as the page title.

The road to enabling an existing ASP.NET MVC web application to serve ASP.NET Webforms contents is actually quite easy. Because the ASP.NET MVC framework is built on top of ASP.NET Webforms, any classic web form will automatically be available from an ASP.NET MVC web application. This means that any ASPX file will be rendered using ASP.NET Webforms, unless the route table contains a matching route for handling an ASP.NET MVC request.
To avoid strange results in a mixed application, consider adding a catch-all route to the route table for ASPX pages, which will ignore any requests to ASP.NET Webforms, and will route only ASP.NET MVC requests. This can be done in the 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);
}
}
}
The above code registers a default ASP.NET MVC route, which will map any URL in the form /Controller/Action/Id into a controller instance and action method. The catch-all route for ASP.NET Webforms looks like this:
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
Whether you are creating a new mixed ASP.NET Webforms-ASP.NET MVC application—or doing a migration, the chances are that you will need to share data between the two technologies. For example, a form can be posted by an ASP.NET Webforms page to an ASP.NET MVC action method.
Because the ASP.NET MVC framework is built on top of ASP.NET Webforms, the following objects are always available in both technologies:
- HttpContext
- Session
- Server
- Request
- Response
- 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.
By default, the views in ASP.NET MVC applications are built the first time that a request comes in. This means that if there is a compilation error in a view, it will only be visible the first time that a user requests for that view to be rendered. To overcome this issue, views can be compiled whenever the ASP.NET MVC application is compiled.
To build views at compile time, the following steps should be executed:
- 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).
- Find the top-most <PropertyGroup> element and add a new element named <MvcBuildViews>:
<MvcBuildViews>: <PropertyGroup>
...
<MvcBuildViews>true</MvcBuildViews> </PropertyGroup> - 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> - 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.
Mixing ASP.NET Webforms and ASP.NET MVC的更多相关文章
- ASP.NET MVC 混搭 ASP.NET WebForms 所导致的 Html.ActionLink/BeginForm 问题
首先,需要了解下这篇博文:<ASP.NET WebForms MapPageRoute 路由配置> 之前,在 ASP.NET MVC 中混搭 ASP.NET WebForms,使用 Map ...
- 【基础版限时免费】致敬WebForms,ASP.NET Core也能这么玩!
ASP.NET WebForms ASP.NET WebForms 随着微软 2000 年的 .Net Framework 一起发布,至今也将近 20 年的时间.相信很多人和我一样,对 WebForm ...
- FineUIPro/Mvc/Core/JS v4.2.0 发布了(老牌ASP.NET控件库,WebForms,ASP.NET MVC,Core,JavaScript)!
还记得 10 年前那个稍微青涩的 ExtAspNet 吗,如今她已脱胎换骨,变成了如下 4 款产品: FineUIPro:基于jQuery的经典款ASP.NET WebForms控件,之前的FineU ...
- ASP.NET Core Razor页面 vs MVC
作为.NET Core 2.0发行版的一部分,还有一些ASP.NET的更新.其中之一是添加了一个新的Web框架来创建"页面",而不需要复杂的ASP.NET MVC.新的Razor页 ...
- 对ASP.NET 5和ASP.NET MVC 6应用程序进行集成测试
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:之前有文章谈到如何对ASP.NET 5的应用程序进行单元测试(需使用xunit),今天 ...
- ASP.NET Core中使用自定义MVC过滤器属性的依赖注入
除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...
- 比较ASP.NET和ASP.NET Core[经典 Asp.Net v和 Asp.Net Core (Asp.Net Core MVC)]
ASP.NET Core是.与.Net Core FrameWork一起发布的ASP.NET 新版本,最初被称为ASP.NET vNext,有一系列的命名变化,ASP.NET 5.0,ASP.NET ...
- [ASP.NET MVC2 系列] ASP.Net MVC教程之《在15分钟内用ASP.Net MVC创建一个电影数据库应用程序》
[ASP.NET MVC2 系列] [ASP.NET MVC2 系列] ASP.Net MVC教程之<在15分钟内用ASP.Net MVC创建一个电影数据库应用程序> ...
- .net mvc 站点自带简易SSL加密传输 Word报告自动生成(例如 导出数据库结构) 微信小程序:动画(Animation) SignalR 设计理念(一) ASP.NET -- WebForm -- ViewState ASP.NET -- 一般处理程序ashx 常用到的一些js方法,记录一下 CryptoJS与C#AES加解密互转
.net mvc 站点自带简易SSL加密传输 因项目需要,传输数据需要加密,因此有了一些经验,现简易抽出来分享! 请求:前端cryptojs用rsa/aes 或 rsa/des加密,后端.net ...
随机推荐
- Codeforces Round #228 (Div. 1) C 贪心
嘎嘎,今天被一些事耽误了,可是还是A了几个题目,这道题还不错 题目链接: 题意:两个人玩游戏,有N堆纸牌,纸牌上有数字,A每次仅仅能取N堆中的 当中一个的顶部的 纸牌,B仅仅能取N堆中的当中一个底部 ...
- 解决ListView中Item的子控件与Item点击事件冲突
常常会碰到在ListView中点击当中一个Item.会一并触发其子控件的点击事件.比如Item中的Button.ImageButton等.导致了点击Item中Button以外区域也会触发Button点 ...
- Redis学习(6)-常用命令
List命令 value值为LinkedList类型. 使用环境: 1,做大数据集合的增删. 2,任务队列.用户任务队列 链表查看 lrange key start end:获取链表从start到en ...
- Java多线程系列目录(转)
转载方便自己学习,转自:Java多线程系列目录(共43篇) http://www.cnblogs.com/skywang12345/p/java_threads_category.html 最近,在研 ...
- 理解并使用.NET 4.5中的HttpClient(转)
原文地址:http://www.cnblogs.com/wywnet/p/httpclient.html HttpClient介绍HttpClient是.NET4.5引入的一个HTTP客户端库,其命名 ...
- 【J2EE之web应用】java集群概念
在学习web应用进行部署的时候,遇到一个名词java集群,(事实上遇到非常多名词╭(╯^╰)╮~~~).不懂意思就查一查! 在这里做个笔记! 没有什么高深见解,就搞明确几个概念,java集群的特点 . ...
- LinkedHashMap插入无序且链式操作
Iterator<Entry<Integer, Integer>> ite=lhmap.entrySet().iterator(); ite.next(); ite.remov ...
- Windows右键菜单设置与应用技巧
http://blog.163.com/lee_honleon/blog/static/555251522008014258896/ 需要修改注册表,挺麻烦的.最好还是把迅雷卸了重装,不会影响什么 ...
- jquery.masonry瀑布流插件的4个使用步骤
1.分别加载jquery插件与jquery.masonry插件两个文件 下载jquery插件:http://jquery.com也可以引用google的cdn外部jquery核心库JS文件下载jque ...
- Python学习笔记011——内置函数exec()
1 描述 把一个字符串当成语句执行 exec() 执行储存在字符串或文件中的 Python 语句,相比于 eval() , exec() 可以执行更复杂的 Python 代码. exec函数和ev ...