在ASP.NET和ASP.NET Core之间共享代码

随着 .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 的文档中找到更多指导。