把ASP.NET MVC 3整合到现行的升级后的ASP.NET 4 Web Forms应用程序中
[原文发表地址] Integrating ASP.NET MVC 3 into existing upgraded ASP.NET 4 Web Forms applications
[原文发表时间] 2011-01-06 12:19 AM
我最近从一位先生那得到了一个有趣的问题,他有一个现行的运行良好的ASP.NET WebForms 2.0 application 。他将之升级到ASP.NET 4后依然运行良好,但如今他想要增加一些ASP.NET MVC页面进去。但他并不想重写这个应用。
几年前我发过一个关于 “ 混合的”ASP.NET应用程序的帖子。其目的是强调这一点:你可以拥有既是WebForms又是MVC的ASP.NET应用程序(以及WCF和 ASMX网页服务等等)。虽然File|New Project对话框给了你一个可在This 和 That之间进行的选择,事实上这都是由ASP.NET所支配的。你尽可以混合及搭配"自助餐厅风格"且以任何你喜欢的组合来创建应用程序。
把ASP.NET MVC 3添加至升级过的ASP.NET 2.0 WebForms应用程序最简单的方法是:
·运行Upgrade Wizard(在Visual Studio 2010中打开Visual Studio2008 Web Application)
·创建一个供参考的默认ASP.NET MVC应用程序(不久你就可将之置之一边)
·使用诸如Beyond Compare的差分工具从ASP.NET MVC单元中把新的web.config条目整合到升级后的 ASP.NET WebForms应用程序中去
·运行成功
如下为上述的更长更为详细的版本。
升级ASP.NET 2.0 WebForms
应用
我创建了一个在.NET 2下运行的简易的Visual Studio 2008 ASP.NET WebForms Application。这是一个简易的计算器。
它运行良好。现在,在Visual Studio 2010里打开这个应用程序。你会看到Conversion/Upgrade Wizard。
依次点击“Next, Next, Yada, Yada, Yada, Finish”。你会得到一个将2.0 application升级.NET Framework 4的提示。点击Yes。
这是同样的、现在已经在Visual Studio 2010里升级过的WebForms应用程序。它依旧运行且仍然是WebForms。或者,更准确地说,它仍是ASP.NET。
我会采用一个新的ASP.NET MVC 3默认应用程序和Beyond Compare并将升级过的应用程序与默认应用程序进行比较。
我会复制这些文件和文件夹:
Content
Controllers
Models
Scripts
Views
Global.asax, Global.asax.cs
现在,这里是升级过后的程序里先前和之后的引用。左边的是旧的右边的是新的引用。
这是我添加的引用。
Microsoft.CSharp
o (as this was a C# app)
System.Web.Mvc
o From \Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies
System.Web.WebPages and System.Web.Razor
o From \Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies
System.ComponentModel.DataAnnotations
接下来,把这些单元添加至 Web.config。再次,使用拆分工具会更加容易一些,你可能会遇到一些困难和错误。
思考:这可能是一个不错的、可供人制作的NuGet程序包…
在 appSettings里添加这些设置:
<appSettings>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
把这些 assembly 元素添加至 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 >
把这些 namespaces添加到页面里:
<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>
如果你在某种情况下运行 IIS7,我确信你会的,请添加这些:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
最后添加assembly 绑定重定向,以防你在 Global Assembly Cache (GAC)里有 ASP.NET MVC 1 or 2 assemblies。
<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>
而且,确保你在 Global.asax.cs中合并以便使你的 Routes在应用程序启动中(被)注册。
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);
}
}
现在,基于这点两种页面我都可以访问。 WebForms页面是磁盘上的文件,因此当我访问 /default.aspx时,ASP.NET就会直接向这个页面发送请求。 ASP.NET 路由引擎已经启用,所以我也可以访问/Home/Index。
如果想做一些花样,我可以添加一个PageRoute,当访问我的 WebForms页面时也有漂亮的 URLs。就像这样,仅仅在 Global.asax里增加一个Route。确保这些简单Route会被首先考虑,因为默认 ASP.NET MVC Route非常地“贪婪”,它会抓住像 /calculator这样的简易 URL。
1 |
routes.MapPageRoute("WebFormThing", "Calculator", "~/Default.aspx"); |
现在我可以访问/Calculator,并且请求被发送到/Default.aspx。当然,我的 ASP.NET MVC 3 Razor页面同样喜欢/Home/Index工作。
最后,只是想指出,靠近一个Razor 页面源的是从我的新应用程序的WebForms部分来的Default.aspx。
您可以拥有这一切,亲爱的读者们。用得开心!