Sharing code between ASP.NET and ASP.NET Core
With the release of .NET 6 there are even more benefits to using ASP.NET Core. But migrating existing code to ASP.NET Core often sounds like a big investment. Today we’ll share how you can accelerate the migration to ASP.NET Core. There are minor changes you can make today that can make it easier to migrate to ASP.NET Core tomorrow.
Before we begin let’s talk about a real scenario. Let’s talk about how to modify code in a 10-year-old application so that it can be shared with ASP.NET Core. In the next sections we’ll give samples that migrate the ShoppingCartController.cs from the MVC Music Store app that was used to demo ASP.NET MVC3.
The first step to migrating this web app is to create a new ASP.NET Core Web App (Model-View-Controller) project. This template will add support for Controllers and map the default route for Controllers in the Program.cs file. Once we have the new project setup, we’ll remove the default HomeController and the view files for Home/Index and Home/Privacy so we can share content from the MVC3 Music Store web app without conflict.
You can share Controllers
The first thing you can share between the two projects is Controllers. Many teams want the new website to work the same as the current one. And when we say “the same” we mean “the same”. If you fix a bug in one project, then you need that same fix to show up in both sites. One of the easiest ways to assure this behavior is to share the same file in both projects. Luckily ASP.NET Core uses the new SDK style project files. That means it’s easy to open the csproj file and add some changes because the files are very readable.
To start sharing a Controller class you’ll need to create an <ItemGroup> and add a reference to the existing class. Here’s a sample that shows how to share the ShoppingCartController.cs by updating the csproj file of the ASP.NET Core project.
<ItemGroup>
<Compile Include="..MvcMusicStoreControllersShoppingCartController.cs" LinkBase="Controllers" />
</ItemGroup>
Okay, now the file is included in the project but you may have guessed that the ASP.NET Core project doesn’t compile anymore. In ASP.NET Core the Controller class doesn’t use System.Web.Mvc it uses Microsoft.AspNetCore.Mvc.
Here’s a sample that shows how the ShoppingCartController.cs can use both namespaces to fix that compiler error.
#if NET
using Microsoft.AspNetCore.Mvc;
#else
using System.Web.Mvc;
#endif
There are other places in the ShoppingCartController that would need to be updated but the approach is the same. Using C# preprocessor directives we can make the class flexible enough to compile for both projects.
For scenarios with large sections of code that work differently for ASP.NET Core you may want to create implementation specific files. A good approach is to create a partial class and extract those code blocks to new method(s) that are different between the two web app targets and use the csproj to control which files are included when building the project.
You can share Models
Now that we can share Controllers we’ll want to share the Models they return. In many scenarios this will just start working when we include them by adding another <ItemGroup> to the csproj file. But if your models also reference System.Web then we can use the same approach we just used for Controllers. Start by updating the namespaces so that the same class file can exist in both projects. Keep using the C# precompiler directives to add ASP.NET Core support.
Here’s a sample that shows how to modify the [Bind] attribute.
#if !NET
[Bind(Exclude="OrderId")]
#endif
public partial class Order
{
[ScaffoldColumn(false)]
#if NET
[BindNever]
#endif
publicintOrderId{ get; set; }
…
…
You can share Views
We can even share views. Using the same approach again we can edit the csproj file to share files like the _Layout.cshtml. And, inside the view you can keep using C# precompiler directives to make the file flexible enough to be used by both projects.
Here’s what it looks like to have a master page with mixed support for Child Actions from ASP.NET and View Components from ASP.NET Core so that we can render the part of the page that knows how many items are in the shopping cart.
@{
#if NET
<text>@awaitComponent.InvokeAsync("CartSummary")</text>
#else
@Html.RenderAction("CartSummary", "ShoppingCart");
#endif
}
Wrapping up
The ability to share code also includes static content like CSS, JavaScript and images. Step-by-step you can build flexibility into your web app today to make your migration to ASP.NET Core easier.
If you would like more detailed guidance to migrate the entire ShoppingCartController.cs you can follow a full walkthrough with samples at MvcMusicStoreMigration. The walkthrough will also demonstrate how you can run both ASP.NET and ASP.NET Core from the same IIS Application Pool to incrementally migrate your web app one controller at a time.
For those planning to start work on their ASP.NET Core migration we’ll share a few more tips.
- Upgrade your NuGet packages so you can use netstandard.
- Change your class libraries to netstandard so you can share code between ASP.NET and ASP.NET Core.
- Find references to
System.Webin your class libraries build interfaces replace them. Use dependency injection so you can easily switch between ASP.NET and ASP.NET Core features.
You can also find more guidance from our docs at Migrate from ASP.NET to ASP.NET Core.
【译】在 ASP.NET 和 ASP.NET Core 之间共享代码
原文 | Ken
翻译 | 郑子铭
随着 .NET 6 的发布,使用 ASP.NET Core 可以获得更多好处。但是将现有代码迁移到 ASP.NET Core 通常听起来像是一项巨大的投资。今天我们将分享如何加速向 ASP.NET Core 的迁移。您今天可以进行一些细微的更改,以便明天更轻松地迁移到 ASP.NET Core。
在我们开始之前,让我们先谈谈一个真实的场景。让我们谈谈如何修改一个有 10 年历史的应用程序中的代码,以便它可以与 ASP.NET Core 共享。在接下来的部分中,我们将提供从用于演示 ASP.NET MVC3 的 MVC 音乐商店应用程序迁移 ShoppingCartController.cs 的示例。
迁移此 Web 应用的第一步是创建一个新的 ASP.NET Core Web 应用(模型-视图-控制器)项目。此模板将添加对控制器的支持,并在 Program.cs 文件中映射控制器的默认路由。一旦我们有了新的项目设置,我们将删除默认的 HomeController 以及 Home/Index 和 Home/Privacy 的视图文件,以便我们可以从 MVC3 Music Store Web 应用程序共享内容而不会发生冲突。
您可以共享控制器
您可以在两个项目之间共享的第一件事是控制器。许多团队希望新网站与当前网站一样工作。当我们说“相同”时,我们的意思是“相同”。如果您修复了一个项目中的错误,那么您需要相同的修复程序出现在两个站点中。确保这种行为的最简单方法之一是在两个项目中共享同一个文件。幸运的是 ASP.NET Core 使用了新的 SDK 风格的项目文件。这意味着很容易打开 csproj 文件并添加一些更改,因为这些文件非常易读。
要开始共享控制器类,您需要创建一个 并添加对现有类的引用。这是一个示例,展示了如何通过更新 ASP.NET Core 项目的 csproj 文件来共享 ShoppingCartController.cs。
<ItemGroup>
<Compile Include="..MvcMusicStoreControllersShoppingCartController.cs" LinkBase="Controllers" />
</ItemGroup>
好的,现在该文件已包含在项目中,但您可能已经猜到 ASP.NET Core 项目不再编译了。在 ASP.NET Core 中,Controller 类不使用 System.Web.Mvc,而是使用 Microsoft.AspNetCore.Mvc。
下面的示例展示了 ShoppingCartController.cs 如何使用这两个命名空间来修复该编译器错误。
#if NET
using Microsoft.AspNetCore.Mvc;
#else
using System.Web.Mvc;
#endif
ShoppingCartController 中还有其他地方需要更新,但方法是相同的。使用 C# 预处理器指令,我们可以使类足够灵活,可以为两个项目进行编译。
对于有大量代码对 ASP.NET Core 工作方式不同的场景,您可能需要创建特定于实现的文件。一个好的方法是创建一个部分类并将这些代码块提取到两个 Web 应用程序目标之间不同的新方法中,并使用 csproj 来控制在构建项目时包含哪些文件。
您可以共享模型
现在我们可以共享控制器,我们想要共享它们返回的模型。在许多情况下,当我们通过向 csproj 文件添加另一个 来包含它们时,这才开始起作用。但是,如果您的模型也引用 System.Web,那么我们可以使用刚刚用于控制器的相同方法。首先更新命名空间,以便相同的类文件可以存在于两个项目中。继续使用 C# 预编译器指令来添加 ASP.NET Core 支持。
这是一个示例,展示了如何修改 [Bind] 属性。
#if !NET
[Bind(Exclude="OrderId")]
#endif
public partial class Order
{
[ScaffoldColumn(false)]
#if NET
[BindNever]
#endif
publicintOrderId{ get; set; }
…
…
您可以共享视图
我们甚至可以共享视图。再次使用相同的方法,我们可以编辑 csproj 文件以共享文件,如 _Layout.cshtml。而且,在视图内部,您可以继续使用 C# 预编译器指令来使文件足够灵活以供两个项目使用。
下面是一个母版页,它混合支持来自 ASP.NET 的子操作和来自 ASP.NET Core 的视图组件,这样我们就可以渲染已知购物车中有多少商品的页面部分。
@{
#if NET
<text>@awaitComponent.InvokeAsync("CartSummary")</text>
#else
@Html.RenderAction("CartSummary", "ShoppingCart");
#endif
}
打包
共享代码的能力还包括 CSS、JavaScript 和图像等静态内容。现在,您可以逐步在您的 Web 应用程序中构建灵活性,以使您更轻松地迁移到 ASP.NET Core。
如果您想要更详细的指导来迁移整个 ShoppingCartController.cs,您可以在 MvcMusicStoreMigration 上使用示例进行完整的演练。该演练还将演示如何从同一个 IIS 应用程序池运行 ASP.NET 和 ASP.NET Core,以一次增量地迁移 Web 应用程序一个控制器。
对于那些计划开始进行 ASP.NET Core 迁移的人,我们将分享一些更多技巧。
- 升级您的 NuGet 包,以便您可以使用 netstandard。
- 将您的类库更改为 netstandard,以便您可以在 ASP.NET 和 ASP.NET Core 之间共享代码。
- 在您的类库构建接口中查找对 System.Web 的引用替换它们。使用依赖注入,以便您可以轻松地在 ASP.NET 和 ASP.NET Core 功能之间切换。
您还可以在从 ASP.NET 迁移到 ASP.NET Core 的文档中找到更多指导。
浙公网安备 33010602011771号