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;
            ...
   		}
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章