Recently the activity room reservation item from asp.net core 2.2 update to asp.net core 3.0, record it, and lessons learned stepped pit upgrade, including but not limited to,
- TargetFramework (
netcoreapp2.2
need to updatenetcoreapp3.0
) - Dependency
- Host/Environment
- Mvc
- Routing
- Swagger
- Dockerfile
- EF (not recommended update)
TargetFramework
Update #
The original project in the netcoreapp2.x
version needs to be updated as netcoreapp3.0
the original package netstandard2.0 based on some of the project depends if the package after the update netstandard2.1
may need to be updated as netstandard2.1
(non-essential, to see the project dependent)
Dependency#
Most of the original package provided in the form nuget when dotnetcore 2.x version, you can nuget direct reference, starting from dotnetcore 3.0 package is no longer published nuget many packages need to refer to the package by reference framework ( FrameworkReference
)
For example, in a class library project <Project Sdk="Microsoft.NET.Sdk">
have such a reference in <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.2" />
3.0 does not publish corresponding nuget package dotnetcore, need to use a reference framework, for example:
<FrameworkReference Include="Microsoft.AspNetCore.App" />
If a Web project <Project Sdk="Microsoft.NET.Sdk.Web">
, Sdk is then directly to the Web targetFramework updated netcoreapp3.0
on it, you do not need to add a reference to the above project in <PackageReference Include="Microsoft.AspNetCore.App"/>
reference can be directly removed
Host && Environment#
The original IHostingEnvironment
instead of the IWebHostEnvironment
original injection IHostingEnvironment
of the modified where necessary to injectIWebHostEnvironment
The original Program
was used WebHostBuilder
instead HostBuilder
and configure ` ConfigureWebHostDefaults
` changes as follows:
MVC#
Service Registration #
3.0 years for MVC Controller
and RazorPages
as well as RazorViews
finishing, injection services we can inject only service they need, if it is WebAPI project can only add Controller
service to need to add corresponding way:
services.AddControllers(); // WebAPI
services.AddControllersWithViews(); // MVC
services.AddRazorPages(); // RazorPage
JSON configuration #
asp.net core 3.0 using Microsoft's new JSON default, but still recommended use Newtonsoft.Json
, mature and to have a lot of special case handling, has become the JSON serialization in .NET facto standard, used as follows:
-
Reference nuget package Microsoft.AspNetCore.Mvc.NewtonsoftJson
-
Configured to use
Newtonsoft.Json
services.AddControllersWithViews()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; // 设置时区为 UTC
});
Rounting #
asp.net core 3.0 recommended endpoint rounting
Configuration is as follows:
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#
Update swagger to rely on the latest version 5.0.0-rc-x (not made stable version, you need to display a preview version to see)
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); });
More Reference:
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 in the base image needs to be updated to 3.0
Example 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"]
Modify the base image is generally not a problem and needs to be noted that if there is useful to dockerfile dotnet publish
and publish the item is not in the directory, you may experience this problem currently, finally can not find the file you want to publish.
dotnet core 3.0 cli have a breaking change, if you want to publish the item not in the current directory, in the 2.x version will be published to your project file's directory, but the 3.0 version will be released in the current directory, for example, execute dotnet publish -c Release ./src/ActivityReservation.csproj -o out
the command:
2.x version will src
generate a directory out
folder
Version 3.0 will generate a directory in the current out
folder, out
folders, and src
at the same level
Detailed questions can refer https://github.com/dotnet/cli/issues/12696
IF #
EF Core 3.0 and 3.0 asp.net core completely independent, can core project in asp.net 3.0's use of EF Core 2.x
EF Core 3.0 has a breaking change, no longer implicit support client rendering data, which allows you to more clearly know what conditions and in what conditions the implementation of the database is performed locally, but the actual trial down, there are still many questions , based on the EF encapsulates the floor, try to splice query expression tree, but when the last execution there will be problems, but the conditions of the simplified client does not actually perform any filtering operation, it temporarily try not recommend ef core 3.0, and you may experience other problems after the update, such as the deployment may encounter this problem in the docker alpine, see issue https://github.com/aspnet/EntityFrameworkCore/issues/18025
The project is now using ef core2.1 + asp.net core3.0 run
More#
Other places should also have a place you want to modify, please add