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;
...
}
}