asp.net core 3.0 更新简记

Intro

最近把活动室预约项目从 asp.net core 2.2 更新到了 asp.net core 3.0,记录一下,升级踩过的坑以及经验总结,包括但不限于

  • TargetFramework (netcoreapp2.2 需要更新为 netcoreapp3.0)
  • Dependency
  • Host/Environment
  • Mvc
  • Routing
  • Swagger
  • Dockerfile
  • EF(不推荐更新)

TargetFramework 更新

原来项目里的 netcoreapp2.x 版本需要更新为 netcoreapp3.0,原来有些基于 netstandard2.0 的项目的包如果有包更新之后依赖 netstandard2.1 可能需要更新为 netstandard2.1(非必须,看项目依赖)

Dependency

原来在 dotnetcore 2.x 版本时大部分的包以 nuget 的形式提供,可以直接通过 nuget 引用,从 dotnetcore 3.0 开始很多包不再发布 nuget 包,需要通过框架引用来引用包(FrameworkReference)

比如在一个类库项目 <Project Sdk="Microsoft.NET.Sdk"> 里有这么一个引用 <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.2" />,在 dotnetcore 3.0 并没有发布对应的 nuget 包,需要使用框架引用,示例如下:

<FrameworkReference Include="Microsoft.AspNetCore.App" />

如果是 Web 项目 <Project Sdk="Microsoft.NET.Sdk.Web">,Sdk 是 Web 的话直接把 targetFramework 更新的 netcoreapp3.0 就可以了,不需要再添加上面的引用了,项目里 <PackageReference Include="Microsoft.AspNetCore.App"/> 的引用也可以直接移除了

Host && Environment

原来的 IHostingEnvironment 改为了 IWebHostEnvironment,原来注入 IHostingEnvironment 的地方需要修改为注入 IWebHostEnvironment

原来 Program 里使用的 WebHostBuilder 改为 HostBuilder 并配置 ``ConfigureWebHostDefaults ,变更如下:

MVC

服务注册

3.0 里 MVC 对 ControllerRazorPages 以及 RazorViews 整理,注入服务的时候我们可以只注入自己需要的服务,如果是 WebAPI 项目可以只添加 Controller 需要的服务即可,对应的添加方式:

services.AddControllers(); // WebAPI
services.AddControllersWithViews(); // MVC
services.AddRazorPages(); // RazorPage

JSON 配置

asp.net core 3.0 默认使用微软新的 JSON,但是推荐还是用 Newtonsoft.Json,比较成熟而且对很多比较特殊的情况都有处理,已然成为了.NET 里 JSON 序列化的事实标准,使用方式如下:

  1. 引用 nuget 包 Microsoft.AspNetCore.Mvc.NewtonsoftJson

  2. 配置使用 Newtonsoft.Json

services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; // 设置时区为 UTC
});

Rounting

asp.net core 3.0 推荐使用 endpoint rounting

配置方式如下:

           app.UseStaticFiles();

            app.UseSwagger()
.UseSwaggerUI(c =>
{
// c.RoutePrefix = string.Empty; //
c.SwaggerEndpoint($"/swagger/{ApplicationHelper.ApplicationName}/swagger.json", "活动室预约系统 API");
c.DocumentTitle = "活动室预约系统 API";
}); app.UseRouting(); // 放在 UseStaticFiles 之后 app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()); app.UseRequestLog();
app.UsePerformanceLog(); app.UseAuthentication();
app.UseAuthorization(); // 放在 UseAuthentication 之后 app.UseEndpoints(endpoints =>
{
endpoints.MapControllers(); // 属性路由
endpoints.MapControllerRoute("Notice", "/Notice/{path}.html", new
{
controller = "Home",
action = "NoticeDetails"
}); // 自定义路由
endpoints.MapControllerRoute(name: "areaRoute", "{area:exists}/{controller=Home}/{action=Index}"); // 区域路由
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); // 默认路由
});

Swagger

更新 swagger 依赖到最新的 5.0.0-rc-x 版本(还没发稳定版,需要显示预览版本才能看到)

services.AddSwaggerGen(options =>
{
options.SwaggerDoc(ApplicationHelper.ApplicationName, new Microsoft.OpenApi.Models.OpenApiInfo { Title = "活动室预约系统 API", Version = "1.0" }); options.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, $"{typeof(Models.Notice).Assembly.GetName().Name}.xml"));
options.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, $"{typeof(API.NoticeController).Assembly.GetName().Name}.xml"), true);
});

更多参考:

https://www.cnblogs.com/laozhang-is-phi/p/11520048.html#autoid-6-0-0

https://www.cnblogs.com/weihanli/p/ues-swagger-in-aspnetcore3_0.html

Docker

Dockerfile 里基础镜像需要更新到 3.0

示例 dockerfile:

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-alpine AS build-env
WORKDIR /src # Copy csproj and restore as distinct layers
COPY ActivityReservation.Common/*.csproj ActivityReservation.Common/
COPY ActivityReservation.Models/*.csproj ActivityReservation.Models/
COPY ActivityReservation.DataAccess/*.csproj ActivityReservation.DataAccess/
COPY ActivityReservation.Business/*.csproj ActivityReservation.Business/
COPY ActivityReservation.Helper/*.csproj ActivityReservation.Helper/
COPY ActivityReservation.WechatAPI/*.csproj ActivityReservation.WechatAPI/
COPY ActivityReservation.AdminLogic/*.csproj ActivityReservation.AdminLogic/
COPY ActivityReservation.API/*.csproj ActivityReservation.API/
COPY ActivityReservation/ActivityReservation.csproj ActivityReservation/ # RUN dotnet restore ActivityReservation/ActivityReservation.csproj
## diff between netcore2.2 and netcore3.0
WORKDIR /src/ActivityReservation
RUN dotnet restore # copy everything and build
COPY . .
RUN dotnet publish -c Release -o out ActivityReservation/ActivityReservation.csproj # build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-alpine LABEL Maintainer="WeihanLi"
WORKDIR /app
COPY --from=build-env /src/ActivityReservation/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "ActivityReservation.dll"]

修改基础镜像一般不会有什么问题,需要注意的是如果 dockerfile 里有用到 dotnet publish 且publish 的项目不在当前目录下,可能会遇到这样的问题,最后找不到要发布的文件。

dotnet core 3.0 cli 有个 breaking change,如果要发布的项目不在当前目录下,在 2.x 版本是会发布到项目文件所在目录下的,但是 3.0 版本会发布在当前目录下,比如说执行dotnet publish -c Release ./src/ActivityReservation.csproj -o out命令:

2.x版本会在 src目录下生成一个 out 文件夹

3.0 版本会在当前目录下生成一个 out 文件夹,out文件夹和 src 同级

详细问题可以参考 https://github.com/dotnet/cli/issues/12696

EF

EF Core 3.0 和 asp.net core 3.0 完全独立,可以在 asp.net core 3.0 的项目里使用 2.x 的 EF Core

EF Core 3.0 有个 breaking change,不再隐式支持客户端渲染数据,这可以让你更清晰的知道哪些条件和在数据库执行的哪些条件是在本地执行的,但是实际试用下来,还是有很多问题的,在 EF 的基础上封装了一层,试用表达式树来拼接查询条件,但是最后执行的时候会有问题,但是简化后的条件实际上并不会在客户端执行任何过滤操作,所以暂时不推荐试用 ef core 3.0,而且更新之后可能会遇到其他的问题,比如在 docker alpine 中部署可能会遇到这个问题,详见issue https://github.com/aspnet/EntityFrameworkCore/issues/18025

现在的项目使用 ef core2.1 + asp.net core3.0 运行

More

其他的地方应该也有需要修改的地方,欢迎补充

Reference

asp.net core 3.0 更新简记的更多相关文章

  1. ASP.NET Core 1.0 开发记录

    官方资料: https://github.com/dotnet/core https://docs.microsoft.com/en-us/aspnet/core https://docs.micro ...

  2. 微软推出ASP.NET Core 2.0,并支持更新Visual Studio 2017

    微软推出ASP.NET Core 2.0的一般可用性,并发布.NET Core 2.0.该公司还推出了其旗舰集成开发环境(IDE)的更新:Visual Studio 2017版本15.3和Visual ...

  3. .NET Core 3.0预览版7中的ASP.NET Core和Blazor更新

    .NET Core 3.0 Preview 7现已推出,它包含一系列ASP.NET Core和Blazor的新更新. 以下是此预览中的新功能列表: 最新的Visual Studio预览包括.NET C ...

  4. asp.net core 3.0 中使用 swagger

    asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...

  5. .NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布

    众所周知,Red Hat和微软正在努力使.NET Core成为Red Hat企业版Linux (RHEL)系统上的一流开发平台选项.这个团队已经一起工作好几个月了,RHEL对.NET有许多需求.今天在 ...

  6. ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录

    升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...

  7. .NET跨平台之旅:将示例站点从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0

    终于将“.NET跨平台之旅”的示例站点 about.cnblogs.com 从 ASP.NET 5 RC1 升级至 ASP.NET Core 1.0 ,经历了不少周折,在这篇博文中记录一下. 从 AS ...

  8. ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介

    概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...

  9. 跨平台运行ASP.NET Core 1.0

    前言 首先提一下微软更名后的叫法: ASP.NET 5 更名为 ASP.NET Core 1.0 .NET Core 更名为 .NET Core 1.0 Entity Framework 7 更名为  ...

随机推荐

  1. 【Edu 67】 补题记录

    CF1187D. Subarray Sorting 想要把一个数x换到前面,x一定是小一点的值.由于B串是固定的,A串可调整,我们可以遍历B数组,对于B[i],找到对于在A数组的位子pos,判断1-p ...

  2. A-Graph Games_2019牛客暑期多校训练营(第三场)

    题意 给出一张无向图,定义S[x]表示与点x直接相连的点集,有两个操作 1 x y表示将第x到第y条边状态变化(若存在则删除,不存在则建立) 2 x y询问S[x]与S[y]是否相等 题解 有一个技巧 ...

  3. BZOJ2655 Calc - dp 拉格朗日插值法

    BZOJ2655 Calc 参考 题意: 给定n,m,mod,问在对mod取模的背景下,从[1,m]中选出n个数相乘可以得到的总和为多少. 思路: 首先可以发现dp方程 ,假定dp[m][n]表示从[ ...

  4. 牛客网暑期ACM多校训练营(第三场) C Shuffle Cards 平衡树 rope的运用

    链接:https://www.nowcoder.com/acm/contest/141/C来源:牛客网 Eddy likes to play cards game since there are al ...

  5. Educational Codeforces Round 69 (Rated for Div. 2)

                                                                                                  A. DIY ...

  6. centos 6.5 搭建DHCP实验

    搭建DHCP服务 安装DHCP服务 挂载光盘:mount /dev/cdrom /qswz 从光盘的安装包中安装DHCP rpm -ivh dhcp-4.1.1-38.P1.el6.centos.i6 ...

  7. spring boot使用常规发送邮件

    spring boot使用常规发送邮件 1.pom.xml文件依赖: <!-- javax.mail begin--> <dependency> <groupId> ...

  8. SAP压缩excel并发送mail案例

    "SAP压缩附件 REPORT ZMMR0033_DEL7 . TYPES: BEGIN OF bin_file,            name TYPE string,          ...

  9. Winform中通过代码设置DevExpress的TextEdit的类型为Numbernic

    场景 使用DevExpress的EditText控件时,需要限制其输入类型为数字. 正常来说是窗体上拖拽一个TextEdit,然后在设计窗口点击小三角,选择Change Mask 但是如果说TextE ...

  10. 3.1、双向循环链表(java实现)

    1.创建节点类 public class CNode<T> { public CNode prev; public CNode next; public T data; public CN ...