asp.net core 3.0 更新简记
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)
比如在一個類庫項目 <ProjectSdk="Microsoft.NET.Sdk"> 里有這么一個引用 <PackageReferenceInclude="Microsoft.AspNetCore.Mvc.Core"Version="2.2.2"/>,在 dotnetcore 3.0 并沒有發布對應的 nuget 包,需要使用框架引用,示例如下:
<FrameworkReference Include="Microsoft.AspNetCore.App" />如果是 Web 項目 <ProjectSdk="Microsoft.NET.Sdk.Web">,Sdk 是 Web 的話直接把 targetFramework 更新的 netcoreapp3.0 就可以了,不需要再添加上面的引用了,項目里 <PackageReferenceInclude="Microsoft.AspNetCore.App"/> 的引用也可以直接移除了
Host && Environment
原來的 IHostingEnvironment 改為了 IWebHostEnvironment,原來注入 IHostingEnvironment 的地方需要修改為注入 IWebHostEnvironment
原來 Program 里使用的 WebHostBuilder 改為 HostBuilder 并配置 `ConfigureWebHostDefaults `,變更如下:
MVC
服務注冊
3.0 里 MVC 對 Controller 和 RazorPages 以及 RazorViews 整理,注入服務的時候我們可以只注入自己需要的服務,如果是 WebAPI 項目可以只添加 Controller 需要的服務即可,對應的添加方式:
services.AddControllers(); // WebAPI services.AddControllersWithViews(); // MVC services.AddRazorPages(); // RazorPageJSON 配置
asp.net core 3.0 默認使用微軟新的 JSON,但是推薦還是用 Newtonsoft.Json,比較成熟而且對很多比較特殊的情況都有處理,已然成為了.NET 里 JSON 序列化的事實標準,使用方式如下:
引用 nuget 包 Microsoft.AspNetCore.Mvc.NewtonsoftJson
配置使用 Newtonsoft.Json
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); });這里沒有用到 OperationFilter,如果用到了 OperationFilter,可能需要引入 Swashbuckle.AspNetCore.Filters 這個包,詳細參考:https://www.cnblogs.com/laozhang-is-phi/p/11520048.html#autoid-6-0-0
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-cRelease./src/ActivityReservation.csproj-oout命令:
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,而且更新之后可能會遇到其他的問題,詳見issue https://github.com/aspnet/EntityFrameworkCore/issues/18025
現在的項目使用 ef core2.1 + asp.net core3.0 運行
More
其他的地方應該也有需要修改的地方,歡迎補充
Reference
https://www.cnblogs.com/stulzq/p/11497624.html
https://www.cnblogs.com/laozhang-is-phi/p/11520048.html
https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio
https://github.com/WeihanLi/ActivityReservation/pull/28/files
總結
以上是生活随笔為你收集整理的asp.net core 3.0 更新简记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【 .NET Core 3.0 】框架之
- 下一篇: 【 .NET Core 3.0 】框架之