Asp.net core 2.2项目迁移3.0过程记录
基本上跟着微软的文档操作就不会有问题。
Asp.net Core2.2迁移到3.0
以下操作均基于Visual Studio 2019
修改项目文件
更新项目框架
在解决方案管理器中右键Asp.net core 项目,选择编辑项目文件。将TargetFramework字段改为3.0;删除AspNetCoreHostingModel元素;移除Microsoft.AspNetCore.App包引用
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<!--IIS进程内托管-->
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
</ItemGroup>
修改项目文件中的包引用
Asp.net Core 3.0中移除了一些2.2中默认包含的引用,也把一些没有默认包含的引用加了进来,基本上就是把Version版本能改成3.0的就改成3.0。
如果你的项目中有用到以下列表的包,那么就需要手动在ItemGroup中加上了。
详细列表请看文章头部的连接。
如果项目有用到Jwt验证的话,以下引用可以作为参考。
2.2
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
</ItemGroup>
3.0
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.2.0" />
</ItemGroup>
修改StartUp.cs
在Using引用里面加上
using Microsoft.Extensions.Hosting;
修改ConfigureServices方法
微软在.net Core 3.0这里估计是很想推自家的Json解析,所以把以前默认的Newtonsoft.Json移出了默认列表,这里我们需要把它加回来,默认用回Newtonsoft.Json(只是因为不想折腾)。
找到设置版本的那一行代码,修改它.
2.2
services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_2)
.AddJsonOptions(option => { option.SerializerSettings.ContractResolver = new DefaultContractResolver(); });
3.0
services.AddControllers().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_3_0)
.AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); });
修改Configure方法
2.2
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 必须先 UseAuthentication再 UseMvc
app.UseAuthentication();
app.UseMvc();
app.UseStaticFiles();
app.UseSwagger();
app.UseSwaggerUI(cfg=> {
cfg.SwaggerEndpoint("/swagger/v1/swagger.json", "Survey Helper API V1");
});
}
3.0
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//app.UseHttpsRedirection();
// 顺序不能随便调
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSwagger();
app.UseSwaggerUI(cfg=> {
cfg.SwaggerEndpoint("/swagger/v1/swagger.json", "Survey Helper API V1");
});
}
这里修改了传参的类型,以及UseAuthentication的调用时机。因为我的项目只是API,之前2.2因为省事直接UseMVC,现在换成了UseRouting+UseEndpoints。2.2必须先UseAuthentication再UseMVC,现在3.0的建议是:请将对 UseAuthentication 和 UseAuthorization 的调用放在之后、UseRouting 和 UseCors,但在 UseEndpoints 之前。
修改Program.cs
因为现在.net core 3.0支持了桌面程序,所以创建宿主的时候自然不会像以前那样直接返回Web宿主。
同样,还是要在Using引用里加上:
using Microsoft.Extensions.Hosting;
这里需要修改CreateWebHostBuilder方法(方法的返回值要改成IHostBuilder,以前是IWebHostBuilder)。
2.2
public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
var host = WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureKestrel((context, option) => {
option.Listen(System.Net.IPAddress.Any, svrPort, (cfg) =>
{
// Configuring
});
}).UseKestrel();
}
3.0
public static IHostBuilder CreateWebHostBuilder(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.ConfigureKestrel((context, option) =>
{
option.Listen(System.Net.IPAddress.Any, svrPort, (cfg) =>
{
// Configuring
});
}).UseKestrel();
});
}
其实就是在ConfigureWebHostDefaults的基础上套多一层CreateDefaultBuilder而已。
至此,如果没有用到Swagger生成API文档的话,应该就可以运行了。
几个细节改动
1.如果用到了Swagger生产API文档,那么就有可能会遇到这个奇怪的TypeLoadException异常。
简单的说就是某个Json模块找不到什么的,这个只要把Swashbuckle.AspNetCore这个Nuget包升到最新就可以了(可能要装预览版)。
2.自定义验证策略的传参有少许变化
如果在代码里有用到自定义验证策略(AddPolicy)
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthorization(option =>
{
option.AddPolicy("AdminIdentify", policy => policy.Requirements.Add(new TokenRequirement()));
});
...
}
那么就不能像这样继续拿到httpcontext了,而且好像已经是再也拿不到了。
public class AdminIdentifyPolicy : AuthorizationHandler<TokenRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TokenRequirement requirement)
{
...
var httpContext = (context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext).HttpContext;
...
}
}