有时候,版本更新太快并非一件好事。虽然,两周一个迭代的“敏捷”开发依然被客户嫌弃交付缓慢,可一边是前端领域“求不要再更新了,学不动了”的声音,一边则是.NET Core从1.x到2.x再到3.x的高歌猛进。版本更新太快,带来的是API的频繁变更,没法造成有效的知识沉淀,就像转眼到了2020年,Python2.x
和Windows7
都引来了“寿终正寝”,可能你都尚未认真地学习过这些知识,忽然就被告知这些知识要过时了,想一想仍是以为挺疯狂啊。最近一直在捣鼓,如何让.NET Core
应用跑在Heroku
平台上,由于Docker
镜像里使用最新的.NET Core 3.1运行时,因此,痛定思痛之余,决定把手头项目升级到3.1。上一次痛苦仍是在2.1升级2.2,这还真没过多长时间。因此呢,这篇博客主要梳理下从2.2升级到3.1过程当中遇到的问题。html
netcoreapp3.1
Microsoft.AspNetCore.App
、Microsoft.AspNetCore.Razor.Design
AspNetCoreHostingModel
,若是项目文件中的值为InProcess
(由于ASP.NET Core 3.0 或更高版本项目默认为进程内承载模型)IWebHostBuilder
调整为IHostBuilder
Microsoft.Extensions.Hosting
Kestrel
配置变动至ConfigureWebHostDefaults()
方法public static IHostBuilder CreateWebHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.ConfigureKestrel(serverOptions => { // Set properties and call methods on options }) .UseStartup<Startup>(); });
若是经过 HostBuilder
手动建立宿主,则须要在 ConfigureWebHostDefaults()
方法中显式调用·UseKestrel()
:前端
public static void Main (string[] args) { var host = new HostBuilder () .UseContentRoot (Directory.GetCurrentDirectory ()) .ConfigureWebHostDefaults (webBuilder => { webBuilder.UseKestrel (serverOptions => { // Set properties and call methods on options }) .UseIISIntegration () .UseStartup<Startup> (); }) .Build (); host.Run (); }
Configure()
方法第二个参数由``IHostingEnvironment调整为
IWebHostEnvironment(须要引用
Microsoft.Extensions.Hosting`)UseMvc()
扩展方法,相应地,删除AddMvc()
及其链式调用相关方法AddMvc()
等价于AddRazorPages()
+ AddControllersWithViews()
AddControllers()
对应WebApi
模板,AddControllersWithViews()
对应MVC
模板,AddRazorPages()
对应SPA
模板传统路由
调整为终结点路由
:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseStaticFiles(); app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { //SignalR路由 endpoints.MapHub<ChatHub>("/chat"); //RazorPages路由 endpoints.MapRazorPages() //特性路由(WebApi) endpoints.MapControllers(); //控制器路由(MVC) endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); }); }
若是但愿继续使用传统路由
,则可使用下列方法任一:git
services.AddMvc(options => options.EnableEndpointRouting = false); services.AddControllers(options => options.EnableEndpointRouting = false); services.AddControllersWithViews(options => options.EnableEndpointRouting = false); services.AddRazorPages().AddMvcOptions(options => options.EnableEndpointRouting = false);
.NET Core 3.0
开始,System.Text.Json
默认做为替代Newtonsoft.json
的新一代JSON API.NET Core 3.0
建立的SignalR项目,服务端返回的JSON数据存在大小写的问题,这是由System.Text.Json
引发的。解决方案是:services.AddSignalR() .AddJsonProtocol(options => options.PayloadSerializerOptions.PropertyNamingPolicy = null);
同理,对于该方案对于services.AddControllers()
同样有效,前提是项目中使用了System.Text.Json
。同理,对于SignalR的客户端项目,咱们有:github
new HubConnectionBuilder() .WithUrl("/chatHub") .AddJsonProtocol(options => { //TODO }) .Build();
@aspnet/signalr
调整为为@microsoft/signalr
:const signalR = require("@microsoft/signalr"); let connection = new signalR.HubConnectionBuilder().withUrl(url).build();
Newtonsoft.json
,则须要安装AspNetCore NewtonsoftJson
。相应地,须要显式调用AddNewtonsoftJson()
扩展方法:services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); });
一样地,AddNewtonsoftJson()
支持AddControllers()
, AddControllersWithViews()
, AddRazorPages()
全部方法web
Microsoft.AspNetCore.Mvc.MvcJsonOptions
,解决方案是:Swashbuckle.AspNetCore
至最新版本(5.0+),调整Swagger中间件配置代码:services.AddSwaggerGen(swagger => { //这里发生了变化,须要引用:Microsoft.OpenApi.Models swagger.SwaggerDoc("v1", new OpenApiInfo { Title = "ynamic WebApi", Version = "v1.0" }); });
.NET Core 3.x
,使用dotnet build
编译项目提示找不到Microsoft.NET.Sdk.Web
。解决方案是:Microsoft.NET.Sdk.Web
为Microsoft.NET.Sdk
能够解决,而这个方法在3.x之后失效。MSBuildSDKsPath
中的SDK版本和实际版本是否一致,尤为是像博主这样从2.0一路升级到3.x的朋友,应该都会遇到这个问题。