ASP.NET Core 实战:将 .NET Core 2.0 项目升级到 .NET Core 2.1

 一、前言

   最近一两个星期,加班,然后回去后弄自己的博客,把自己的电脑从 Windows 10 改到 Ubuntu 18.10 又弄回 Windows 10,原本计划的学习 Vue 中生命周期的相关知识目前也没有任何的进展,嗯,罪过罪过。看了眼时间,11月也快要结束了,准备补上一篇如何将我们的 .NET Core 2.0 版本的程序升级到 .NET Core 2.1 版本,好歹也算多学了一点。

   在上一篇的博客中(ASP.NET Core 实战:Linux 小白的 .NET Core 部署之路),试着将我之前写的 ASP.NET Core 2.0 的项目部署到 Linux 服务器上,采用的是微软官方推荐的 Nginx + Supervisor 的方式,评论区的小伙伴提出了使用 Docker 的方式可以更便捷的实现,同时对于新手来说也会更好上手。嗯,新手向的使用 Docker 部署 ASP.NET Core 项目也会在之后的文章中体现。欢迎多多关注啊。

 二、起因

   .NET Core 2.1 发布于今年的5月30号,从版本号我们可以看出这只是一个小版本的升级,从微软官方发布的更新信息来看,对比于 .NET Core 2.0 版本,更多的是进行性能的优化、对于 .NET Core Runtime、.NET Core tools 的更改以及增加 API 或是增加更多的系统支持。

   在上一篇的文章中,我们在 Linux 服务器上构建我们的 .NET Core 运行环境时,安装的是最新版本的 .NET Core Runtime,而部署的程序 .NET Core 版本则是 .NET Core 2.0(项目源码地址:https://github.com/Lanesra712/Danvic.PSU),因为并没有采取 Docker 部署的缘故,这里程序与运行环境的版本差异,可能导致某些我们的程序产生某些我们并不能复现的问题,所以,升级我们的程序就显得很有必要了。

  PS:如果你要在实际的生产项目升级你的 .NET Core 版本,慎重,慎重,再慎重!!!

 三、Step by Step

  1、修改我们的项目目标框架

  在更新 VS 2017 的过程中,我们的 .NET Core 版本也会进行更新,当然,如果你的电脑中没有安装 .NET Core 2.1 SDK,则需要你从官网上下载最新版的 SDK 进行安装。当我们已经安装好 .NET Core 2.1 SDK 后,就可以将我们原来程序的目标框架更改为 .NET Core 2.1。

  右键我们的项目,我们可以直接编辑 csproj 文件 或者通过打开属性选项进行可视化的修改。其实这里我们通过属性页面进行编辑实质上就是编辑我们的 csproj 文件。

  同时,为了保持我们的项目框架的一致性,我们需要将我们引用的类库的目标框架同样修改成 .NET Core 2.1。

  2、替换 Nuget 包引用

  在 .NET Core 2.1 版本中 微软将 Microsoft.AspNetCore.All 这个 .NET Core 的基础 DLL 更换成了 Microsoft.AspNetCore.App,因此,在更新了程序的目标框架后我们还需要将我们程序删除对于 Microsoft.AspNetCore.All 的引用,同时添加对于 Microsoft.AspNetCore.App 的引用。

  在 Microsoft.AspNetCore.App 中不包含了以下 Nuget package,如果你对于这些 package 有需要的话,你可以在项目中引用这些 package。

Microsoft.AspNetCore.ApplicationInsights.HostingStartup
Microsoft.AspNetCore.AzureAppServices.HostingStartup
Microsoft.AspNetCore.AzureAppServicesIntegration
Microsoft.AspNetCore.DataProtection.AzureKeyVault
Microsoft.AspNetCore.DataProtection.AzureStorage
Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv
Microsoft.AspNetCore.SignalR.Redis
Microsoft.Data.Sqlite
Microsoft.Data.Sqlite.Core
Microsoft.EntityFrameworkCore.Sqlite
Microsoft.EntityFrameworkCore.Sqlite.Core
Microsoft.Extensions.Caching.Redis
Microsoft.Extensions.Configuration.AzureKeyVault
Microsoft.Extensions.Logging.AzureAppServices
Microsoft.VisualStudio.Web.BrowserLink

  在引用 Microsoft.AspNetCore.App 的时候,可能会提示缺少某些依赖项或者提示我们原来引用的 Nuget 包版本不满足 Microsoft.AspNetCore.App,我们只需要根据提示的错误信息将我们缺少的依赖项添加上或者将不满足要求的版本升级就可以了。

  例如我在升级 PSU.EFCore 这个类库中时,发现引用的程序集版本不满足我们我们使用 2.1.6 版本的 Microsoft.AspNetCore.App ,我们只需要将这些引用的 DLL 进行升级,再安装我们最新版本的 Microsoft.AspNetCore.App。

  在安装 .NET Core 2.1 SDK 之后,下列的 tools 已经被包含在最新版本的 .NET Core CLI 中,因此,我们可以在 csproj 文件中删除 DotNetCliToolReference 节点下的这些引用的 Nuget 包。

Microsoft.DotNet.Watcher.Tools (dotnet watch)
Microsoft.EntityFrameworkCore.Tools.DotNet (dotnet ef)
Microsoft.Extensions.Caching.SqlConfig.Tools (dotnet sql-cache)
Microsoft.Extensions.SecretManager.Tools (dotnet user-secrets)

  对于 DotNetCliToolReference 节点下的 dotnet-aspnet-codegenerator(用于生成 MVC中的 controllers 和 views 模板) Nuget 包,你同样可以选择删除这个引用,同时使用全局安装 tool 来代替它。

dotnet tool install -g dotnet-aspnet-codegenerator

  3、基于 ASP.NET Core 2.1 代码惯例的更改

  在 .NET Core 升级到 2.1 版本后,ASP.NET Core 相应的也进行了一些更新,我们创建的模板中的一些基础代码也进行了修改。例如在下面示例中,我们使用 .NET Core 2.0 版本创建的 MVC 项目中的 Program.cs 代码结构与使用 .NET Core 2.1 生成的模板代码是有一定差异的。

//ASP.NET Core 2.0
namespace WebApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}
//ASP.NET Core 2.1
namespace WebApp1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>();
    }
}

  这里我们按照最新版本的模板代码对我们的 Program.cs 代码结构进行修改。

  同样的,在 Startup.cs 文件中,ASP.NET Core 2.1 版本增加了对于 GDPR 的支持(欧盟的一项政策,当我们需要收集用户的数据时,必须以「简洁、透明且易懂的形式,清晰和平白的语言」向用户说明,例如这里我们使用了 cookie、session 来存储用户的数据,我们就需要提前告知用户),对于 HTTPS 的重定向支持以及增加了 SetCompatibilityVersion 方法允许应用程序选择加入或退出ASP.NET MVC Core 2.1+中引入的可能中断的行为更改(嗯,看了一圈还是不明白到底是干什么的)。

  4、其它修改

  在 ASP.NET Core MVC 框架版本的更新中,同样对于引用的一些 JS 类库进行了升级,这里我就不升级了,主要为我们的程序添加对于 GDPR 政策的提示。以及要求我们的程序以 HTTPS 的形式进行访问。

  首先我们创建一个分布视图 _CookieConsentPartial 用来提示我们需要收集用户的信息,在 SecretController 控制器中添加一个 Action 用来显示我们的隐私政策,同时在我们的模板页面中引用创建的分布视图,这里的样式就不做任何的调整了,只是做个示例。

@using Microsoft.AspNetCore.Http.Features

@{
    var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
    var showBanner = !consentFeature?.CanTrack ?? false;
    var cookieString = consentFeature?.CreateConsentCookie();
}

@if (showBanner)
{
    <nav id="cookieConsent" class="navbar navbar-default navbar-fixed-top" role="alert">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#cookieConsent .navbar-collapse">
                    <span class="sr-only">Toggle cookie consent banner</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <span class="navbar-brand"><span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span></span>
            </div>
            <div class="collapse navbar-collapse">
                <p class="navbar-text">
                    Use this space to summarize your privacy and cookie use policy.
                </p>
                <div class="navbar-right">
                    <a asp-controller="Secret" asp-action="Privacy" class="btn btn-info navbar-btn">Learn More</a>
                    <button type="button" class="btn btn-default navbar-btn" data-cookie-string="@cookieString">Accept</button>
                </div>
            </div>
        </div>
    </nav>
    <script>
        (function () {
            document.querySelector("#cookieConsent button[data-cookie-string]").addEventListener("click", function (el) {
                document.cookie = el.target.dataset.cookieString;
                document.querySelector("#cookieConsent").classList.add("hidden");
            }, false);
        })();
    </script>
}
//在网站的首页(登录页面)中引用分布视图
<partial name="_CookieConsentPartial" />
/// <summary>
/// 隐私政策
/// </summary>
/// <returns></returns>
[AllowAnonymous]
public IActionResult Privacy()
{
    return View();
}

  在之前的步骤中,我们在代码中支持了使用 HTTPS 请求访问,现在我们就可以启用 SSL 来使我们通过 HTTPS 请求来访问我们的项目。

 四、总结

   从 .NET Core 2.0 升级到 .NET Core 2.1的整个过程来看,项目整体改动不多,在发布项目时,我们可以发现,发布后的项目的大小缩小了很多,同时还提供了对于独立部署的支持,不用做过多的操作,就可以获得一些新的优秀特性,总的来说还是很值得升级的。

  注:

  1、依赖部署(FDD):项目依赖于目标服务器系统上的存在的系统级 .NET Core 环境,发布后的应用仅包含其自己的代码和其它位于 .NET Core 系统级库外的第三方依赖项。

  2、独立部署(SCD):发布后的项目需要包含发布后的程序所需要的全部组件(.NET Core 环境、第三方依赖项、程序代码),不依赖于目标服务器系统上的 .NET Core 环境。