ASP.NET Core 2.0が3.0にアップグレードされた変化と問題

14657 ワード

前言


はい.NET Core 2.0がリリースされた際、ブロガーも熱いうちにASPを使用する.NET Core 2.0は独立したブログサイトを書いたが、今はちょうどいい.NET Core 3.0のリリースにあたり、このサイトをアップグレードしました.
アップグレード中に発生した変化と問題について説明します.同时に広告も一波、みんなを歓迎して多く私のブログに来てぶらぶらします:落阁しません-1つ.NETプログラマーの個人ブログ

本文


ホスト変化


Program.csでWebHostBuilderがHostBuilder,ASPになる.NET Core 3.0は汎用ホストを使用しており、ホスト構成も変更されており、主にコンフィギュレーションWebHostDefaultsメソッドに集中しています.
以下は、アップグレード前後のコードです.
 1 //   :ASP.NET Core 2.0
 2 WebHost.CreateDefaultBuilder(args)
 3     .UseUrls("http://127.0.0.1:5002")
 4     .UseStartup()
 5     .ConfigureLogging(logging =>
 6     {
 7         logging.ClearProviders();
 8         logging.SetMinimumLevel(LogLevel.Trace);
 9     })
10     .UseNLog();
11 //   :ASP.NET Core 3.0
12 Host.CreateDefaultBuilder(args)
13     .ConfigureWebHostDefaults(webBuilder =>
14     {
15         webBuilder.UseStartup()
16         .UseUrls("http://127.0.0.1:5002")
17         .ConfigureLogging(logging =>
18         {
19             logging.ClearProviders();
20             logging.SetMinimumLevel(LogLevel.Trace);
21         })
22         .UseNLog();
23     });

Startup.cs変化


サービスの構成:AddControllersWithViewsが元のAddMVCに代わった.
パイプラインの構成:UseMVC、UseSignalRは、UseEndpointsに統一的に置き換えられます.また、UseRoutingが追加されました.UseAuthentication、UseAuthorizationは、UseRoutingとuseEndpointsの間にある必要があります.
 1 //   
 2 app.UseAuthentication();
 3 app.UseSignalR(routes =>
 4 {
 5     routes.MapHub("/chatroom");
 6 });
 7 app.UseMvc(routes =>
 8 {
 9     routes.MapRoute(
10         name: "default",
11         template: "{controller=Home}/{action=Index}/{id?}");
12 });
13 //   
14 app.UseRouting();
15 app.UseAuthentication();
16 app.UseAuthorization();
17 app.UseEndpoints(endpoints =>
18 {
19     endpoints.MapControllerRoute(
20         name: "default",
21         pattern: "{controller=Home}/{action=Index}/{id?}");
22     endpoints.MapHub("/chatroom");
23 });

QQログインの問題


ASPにアップグレードNET Core 3.0以降、以前使用していたMicrosoft.AspNetCore.Authentication.QQパッケージが正常に使用できなくなり、ソースコードのデバッグを経て、OAuthHandlerの中のExchangeCodeAsyncなどの方法の書き換えが有効になっていないため、QQから返されたデータ(QQから返されたデータが特殊)がJsonに変換されたときにエラーが発生したことに気づきました.NugetでMicrosoft.AspNetCore.Authentication.OAuthは依然として2.2.4バージョンであり、Microsoft.AspNetCore.Authentication.MicrosoftAccount、Microsoft.AspNetCore.Authentication.Googleなどのパッケージは3.0.0にアップグレードされています.https://github.com/aspnet/AspNetCore/issues/10991確かに変更されましたが、私たちが入手できるのは依然として2.2.4版です.
最後にGithubでサードパーティ認証の集合項目が見つかりました.https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providersああ、上にQQ登録のパッケージAspNetが見つかりました.Security.OAuth.QQ.
Nugetでは2.1.0のままで、これは明らかに使えませんが、mygetでは3.0.0プレビュー版があります.
PM命令に従ってインストールすると、このパッケージに対応するバージョンが見つからないというメッセージが表示されます.最新版は2.1.0なので、nupkgファイルを手動でダウンロードします.
使い方は前とあまり違いませんが、2つの細かい変更があります.
1.AppIdとAppKeyを統一したClientIdとClientSecertに変更
2.openidはカスタムClaim名にマッピングできないので、後で処理する場合はシステム定義のClaimType.NameIdentifierが取得します.

Jsonシーケンス化問題


.NET Core 3.0は新しいJSON APIを導入し、ASP.NET CoreはNewtonsoftを削除しました.Jsonの参照は、デフォルトではSystemを使用します.Text.JsonはJsonをシーケンス化し、新しいJSON APIは主な性能を持っているので、JSONはありません.NET全面.
Entity Frameworkを使用するため、エンティティクラスを直接シーケンス化すると、ナビゲーション属性に循環参照の問題が発生し、System.Text.Jsonは、ループリファレンスの問題を解決するための構成を提供していません.
Githubで探したところ、公式にもこの問題に言及されているようですが、3.0バージョンでは解決策が提供されていません.https://github.com/dotnet/corefx/issues/38579
従って、従来のJSON API、すなわちJSONを使用せざるを得ない.NET(Newtonsoft.Json)
ASP.NET Core 3.0ではNewtonsoftを使用する.Json、Microsoftをインストールする必要があります.AspNetCore.Mvc.NewtonsoftJsonパッケージは、Startupで構成されています.次のようになります.
 1 //   
 2 services.AddMvc()
 3     .AddJsonOptions(options =>
 4     {
 5         options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //    key     
 6         options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
 7         options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
 8         options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;    //      
 9     });
10 //   (    Microsoft.AspNetCore.Mvc.NewtonsoftJson )
11 services.AddControllersWithViews()
12     .AddNewtonsoftJson(options =>
13     {
14         options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); //    key     
15         options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
16         options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
17         options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;    //      
18     });

EFCoreクライアント評価


EF Core 3.0ではクライアント評価はサポートされていません.Linqでクエリーしてから手動で演算する必要があります.
 1 //   
 2 detailModel.SimilarArticles = await _dbContext.Article
 3     .Where(s => s.Status == (int)CommonStatus.Valid && StringSimilarity.Calculate(article.Title, s.Title) > 0.3m && s.Id != article.Id)
 4     .Select(s => new Article()
 5     {
 6         Id = s.Id,
 7         CreateTime = s.CreateTime,
 8         Title = s.Title
 9     })
10     .OrderBy(s => Guid.NewGuid())
11     .Take(8)
12     .ToListAsync();
13 //   
14 var similarArticles = await _dbContext.Article
15     .Where(s => s.Status == (int)CommonStatus.Valid && s.Id != article.Id)
16     .Select(s => new Article()
17     {
18         Id = s.Id,
19         CreateTime = s.CreateTime,
20         Title = s.Title
21     })
22     .ToListAsync();
23 similarArticles = similarArticles.Where(s => StringSimilarity.Calculate(article.Title, s.Title) > 0.3m).OrderBy(s => Guid.NewGuid()).Take(8).ToList();

上記のコードセグメントは、StringSimilarityのある文章のタイトルに似た文章をフィルタリングするものである.Calculate(string,string)メソッドはクライアント上で2つのタイトルの類似度を計算するアルゴリズムであり,3.0以降EF CoreはLinqクエリに直接書くことをサポートせず,異常を報告し,Linq文を翻訳できないことを意味する.
実際にアップグレード前後の2つの書き方で生成されるSQLは同じです.

もっと多くの問題は未定で、まずここに紹介します。


ご開封ありがとうございます、斧正をお願いします!
この文書は、次のように最初に発表されました.https://www.leo96.com/article/detail/47