从 ASP.NET Core 2.1 迁移到 2.2

作者:Scott Addie

本文介绍如何将现有 ASP.NET Core 2.1 项目更新为 ASP.NET Core 2.2。

先决条件

警告

如果使用 Visual Studio 2017,请参阅 dotnet/sdk 问题 #3124,以了解无法与 Visual Studio 一起使用的 .NET Core SDK 版本的信息。

更新目标框架名字对象 (TFM)

面向 .NET Core 的项目需使用 .NET Core 2.2 版或更高版本的 TFM。 在项目文件中,通过 netcoreapp2.2 更新 <TargetFramework> 节点的内部文本:

<TargetFramework>netcoreapp2.2</TargetFramework>

面向 .NET Framework 的项目需继续使用 .NET Framework 4.6.1 版或更高版本的 TFM:

<TargetFramework>net461</TargetFramework>

采用 IIS 进程内托管模型

若要采用 IIS 进程内托管模型,请将值为 InProcess<AspNetCoreHostingModel> 属性添加到项目文件中的 <PropertyGroup>

<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>

面向 .NET Framework 的 ASP.NET Core 应用不支持进程内托管模型。

有关详细信息,请参阅用于 IIS 的 ASP.NET Core 模块 (ANCM)

更新自定义 web.config 文件

对于项目根中使用自定义 web.config 文件的项目,要生成发布的 web.config 文件,请执行以下操作

  • 在添加 ASP.NET Core 模块 (name="aspNetCore") 的 <handlers> 项中,将 modules 属性值从 AspNetCoreModule 更改为 AspNetCoreModuleV2
  • <aspNetCore> 元素中,添加托管模型特性 (hostingModel="InProcess")。

有关详细信息和 web.config 文件的示例,请参阅用于 IIS 的 ASP.NET Core 模块 (ANCM)

更新包引用

如果面向 .NET Core,则在项目文件中删除元包引用的 Version 特性。 包含 Version 特性会导致出现以下警告:

A PackageReference to 'Microsoft.AspNetCore.App' specified a Version of `2.2.0`. Specifying the version of this package is not recommended. For more information, see https://aka.ms/sdkimplicitrefs

有关详细信息,请参阅 ASP.NET Core 的 Microsoft.AspNetCore.App 元包

元包引用应类似于以下 <PackageReference /> 节点:

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

如果面向 .NET Framework,请将每个包引用的 Version 特性更新为 2.2.0 或更高版本。 以下是面向 .NET Framework 的典型 ASP.NET Core 2.2 项目中的包引用:

<ItemGroup>
  <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
  <PackageReference Include="Microsoft.AspNetCore.CookiePolicy" Version="2.2.0" />
  <PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.2.0" />
  <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
  <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
</ItemGroup>

如果引用 Microsoft.AspNetCore.Razor.Design 包,请将其 Version 特性更新为 2.2.0 或更高版本。 否则,会导致出现以下错误:

Detected package downgrade: Microsoft.AspNetCore.Razor.Design from 2.2.0 to 2.1.2. Reference the package directly from the project to select a different version.

在 global.json 中更新 .NET Core SDK 版本

如果解决方案依靠 global.json 文件来面向特定的 .NET Core SDK 版本,请将其 version 属性更新为计算机上安装的 2.2 版本:

{
  "sdk": {
    "version": "2.2.100"
  }
}

更新启动设置

如果使用 Visual Studio Code,请更新项目的启动设置文件 (.vscode/launch.json).vscode/launch.jsonprogram 路径应引用新 TFM:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": ".NET Core Launch (web)",
            "type": "coreclr",
            "request": "launch",
            "preLaunchTask": "build",
            "program": "${workspaceFolder}/bin/Debug/netcoreapp2.2/test-app.dll",
            "args": [],
            "cwd": "${workspaceFolder}",
            "stopAtEntry": false,
            "internalConsoleOptions": "openOnSessionStart",
            "launchBrowser": {
                "enabled": true,
                "args": "${auto-detect-url}",
                "windows": {
                    "command": "cmd.exe",
                    "args": "/C start ${auto-detect-url}"
                },
                "osx": {
                    "command": "open"
                },
                "linux": {
                    "command": "xdg-open"
                }
            },
            "env": {
                "ASPNETCORE_ENVIRONMENT": "Development"
            },
            "sourceFileMap": {
                "/Views": "${workspaceFolder}/Views"
            }
        },
        {
            "name": ".NET Core Attach",
            "type": "coreclr",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

更新 Kestrel 配置

如果应用通过调用 ProgramCreateWebHostBuilder 方法 中的 CreateDefaultBuilder 来调用 UseKestrel,请调用 ConfigureKestrel 而非 UseKestrel 来配置 Kestrel 服务器,以避免与 IIS 进程内托管模型发生冲突:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            // Set properties and call methods on options
        });

如果应用不调用 CreateDefaultBuilder 并在 Program 类中手动生成主机,请在调用 ConfigureKestrel之前调用 UseKestrel

public static void Main(string[] args)
{
    var host = new WebHostBuilder()
        .UseContentRoot(Directory.GetCurrentDirectory())
        .UseKestrel()
        .UseIISIntegration()
        .UseStartup<Startup>()
        .ConfigureKestrel((context, options) =>
        {
            // Set properties and call methods on options
        })
        .Build();

    host.Run();
}

有关详细信息,请参阅 ASP.NET Core 中的 Kestrel Web 服务器

更新兼容性版本

Startup.ConfigureServices 中的兼容性版本更新为 Version_2_2

services.AddMvc()
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

更新 CORS 策略

在 ASP.NET Core 2.2 中,如果策略允许任何来源并允许凭据,则 CORS 中间件会使用通配符源 (*) 进行响应。 如果指定通配符源 (*),则不支持凭据,并且浏览器将不允许 CORS 请求。 有关详细信息,包括如何在客户端解决此问题的选项,请参阅 MDN Web 文档

若要在服务器上解决此问题,请执行下列操作之一:

  • 修改 CORS 策略以不再允许凭据。 也就是说,在配置策略时,删除对 AllowCredentials 的调用。
  • 如果 CORS 请求需要提供凭据才能成功,请修改策略以指定允许的主机。 例如,请使用 builder.WithOrigins("https://api.example1.com", "https://example2.com") 而不是使用 AllowAnyOrigin

更新 Docker 映像

下表显示了 Docker 映像标记更改:

2.1 2.2
microsoft/dotnet:2.1-aspnetcore-runtime mcr.microsoft.com/dotnet/core/aspnet:2.2
microsoft/dotnet:2.1-sdk mcr.microsoft.com/dotnet/core/sdk:2.2

将 Dockerfile 中的 FROM 行更改为使用上表的 2.2 列中的新映像标记。

使用 IIS 进程内托管时,在 Visual Studio 中手动生成

Visual Studio 的“在浏览器请求时自动生成”体验无法与 IIS 进程内托管模型一起使用。 使用进程内托管时,必须手动重新生成项目。 我们已计划对 Visual Studio 的未来版本改进此体验。

更新日志记录代码

建议的日志记录配置代码未从 2.1 更改为 2.2,但在 2.1 中仍然有效的某些 1.x 编码模式在 2.2 中不再适用。

如果应用在 Startup 类中执行日志记录提供程序初始化、筛选和配置加载,请将该代码移动到 Program.Main

  • 提供程序初始化:

    1.x 示例:

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole();
    }
    

    2.2 示例:

    
    public static void Main(string[] args)
    {
        var webHost = new WebHostBuilder()
            // ...
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConsole();
            })
            // ...
    }
    
  • 筛选:

    1.x 示例:

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(LogLevel.Information);
        // or
        loggerFactory.AddConsole((category, level) => 
            category == "A" || level == LogLevel.Critical);
    }
    

    2.2 示例:

    public static void Main(string[] args)
    {
        var webHost = new WebHostBuilder()
            // ...
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConsole()
                       .AddFilter<ConsoleLoggerProvider>
                           (category: null, level: LogLevel.Information)
                       // or
                       .AddFilter<ConsoleLoggerProvider>
                           ((category, level) => category == "A" ||
                               level == LogLevel.Critical)
                );
            })
            // ...
    }
    
  • 配置加载:

    1.x 示例:

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration);
    }
    

    2.2 示例:

    public static void Main(string[] args)
    {
        var webHost = new WebHostBuilder()
            // ...
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                logging.AddConsole();
            })
            // ...
    }
    

有关详细信息,请参阅 .NET Core 和 ASP.NET Core 中的日志记录

ASP.NET Core 模块 (ANCM)

如果在安装 Visual Studio 时未选择 ASP.NET Core 模块 (ANCM) 组件,或者系统上安装了 ANCM 的早期版本,请下载最新的 .NET Core 托管捆绑包安装程序(直接下载)并运行该安装程序。 有关详细信息,请参阅托管捆绑包

其他资源