.net6发布后,迫不及待的将.net5的一个项目迁移到了.net6,这里记录迁移过程中遇到的问题,详细的迁移可以参考微软这个地址 参考
首先要安装最新版的vs2022才能开发.net6项目。我这里没有直接去.net5项目上做更改,而是用vs2022新建一个.net6的asp.netcore web空项目,然后再把.net5的代码copy过来
.net6最大的变化在于Startup.cs和 Program.cs文件
最小宿主模型:
大大减少了创建应用程序所需的文件和代码行数。 只有一个文件需要四行代码。
Startup.cs将和 Program.cs 合并到单个 Program.cs 文件中。
使用 顶级语句 来最大程度地减少应用程序所需的代码。
使用全局 using 指令消除或最大程度地减少所需的 using 语句行数。
以上是微软官方的话语,其实就是微软化繁为简,把之前startup里的代码又放回了program里面,同时为了省事把main函数以及花括号通通删掉,namespace也做了优化,最终我们看到的program变成了这样
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
在我们的.net5项目里,我们使用了NewtonsoftJson组件以及IHttpContextAccessor来获取httpcontext,startup类的代码如下
public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddNewtonsoftJson(options => { // 设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //忽略null值 options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); services.AddMvc(); services.AddHealthChecks(); //注入HttpContextAccessor services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHttpContextAccessor accessor) { //设置HttpContextAccessor实例 HttpContextHelper._accessor = accessor; ... }
根据微软官方说法
builder.Services.AddControllers().AddNewtonsoftJson(options => { // 设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //忽略null值 options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); //注入HttpContextAccessor builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); ... var app = builder.Build(); //初始化HttpContextAccessor实例 var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); HttpContextHelper._accessor = httpContextAccessor;
当然我们可以通过扩展方法来优化下代码
public static void AddHttpContextAccessor(this IServiceCollection services) { services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); } public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app) { var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>(); HttpContextHelper._accessor = httpContextAccessor; return app; }
通过以上改造,.net6项目正常运行了,后面就是把.net5项目的业务代码copy到新项目即可
最终的代码如下
using Microsoft.AspNetCore.ResponseCompression; using Swashbuckle.AspNetCore.Swagger; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers().AddNewtonsoftJson(options => { // 设置时间格式 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //忽略null值 options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }); builder.Services.AddResponseCompression(options => { options.Providers.Add<GzipCompressionProvider>(); }); builder.Services.AddMvc(); builder.Services.AddHealthChecks(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "My-API", Version = "v1" }); var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); var xmlPath = Path.Combine(basePath, "SwaggerDemo.xml"); c.IncludeXmlComments(xmlPath); }); //注入HttpContextAccessor builder.Services.AddHttpContextAccessor(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My-API"); }); } //设置HttpContextAccessor实例 app.UseStaticHttpContext(); ... app.Run();