ASP.NET Core 2.x から 3.0 への移行をプライベートと仕事のアプリケーション両方で試しました。
基本的にはドキュメントの通り行えば良いので簡単ですが、少し別途対応が必要だった部分があるのでメモとして残しておきます。あと Endpoint Routing 周りについて少し追加します。
Razor 系のツールを削除する
2.2 まではテンプレートから View を作る時にインストールされていた Microsoft.AspNetCore.Razor.Design
は 3.0 ではサポートされなくなりました。
インストールされていると Visual Studio でのビルド時にエラーとなるので削除します。
他にも発行時に Razor をプリコンパイルする Microsoft.AspNetCore.Mvc.Razor.ViewCompilation
というパッケージがインストールされているケースがありますが、既に SDK 側にプリコンパイル機能が組み込まれ不要になっているので削除しておきましょう。
パッケージ更新後に 3.0.0 になっていないものは大体サポートされなくなったものなので削除した方が良いです。必要な場合は Visual Studio が都度インストールしてくれます。
Entity Framework Core 関連パッケージの追加
3.0 の MicrosoftAspNetCore.App
からは Entity Framework Core 関連が除外されているので、2.2 からの移行時にパッケージが見つからないというエラーが出るはずです。
大抵は Microsoft.EntityFrameworkCore.SqlServer
をインストールすれば良いですが、Identity や DB Migration 周りで以下のパッケージに依存していることもあるので、インストールする必要があります。
Microsoft.AspNetCore.Identity.EntityFrameworkCore
- ASP.NET Core Identity を Entity Framework Core で使う場合に必要
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
UseDatabaseErrorPage
などを使う場合に必要
開発時に DB がない場合はブラウザから作成できる UseDatabaseErrorPage
は便利なので使っているケースは多いでしょう。これまで暗黙的に参照されていたものはパッケージ名がぱっと見は分からないので、都度調べる必要があるのが少し手間です。
Entity Framework Core 3.0 は Azure Functions で利用不可
Entity Framework Core 3.0 はターゲットが .NET Standard 2.1 となったため、現状 .NET Core 2.2 をターゲットとする Azure Functions v2 では利用できないです。
Azure Functions v3 では .NET Core 3.0 に対応するようになるので、その時までは 2.2 を使い続ける必要があります。.NET Standard 2.1 のみ対応するパッケージは同様にインストール出来ません。
3.0 から完全に消えたクラス
.NET API Browser や GitHub から検索してヒットしないクラスやメソッドは 3.0 から消えたので、別の方法に変えたり使っていない場合は削除する必要があります。
今回の移行時には ASP.NET Core Identity で使われていた AuthenticationDescription
が該当しました。
テンプレートから自動生成されたクラスで使われていたのと、そもそも参照されていなかったのでクラスごと削除して対応しました。不要なものを残していると苦労します。
ASP.NET Core 3.0 の Endpoint Routing を理解する
以前にも書いた気がしますが、これまでの ASP.NET Core のルーティングは ASP.NET MVC の初期に実装された仕組みから大きく変わっておらず、各フレームワークごとにルーティングの仕組みが用意されてきました。
更に問題となるのが、CORS や認可周りが各フレームワークごとに別々に用意されていたことです。これはこれまでのルーティングの仕組み上、共通の処理を書くことが出来なかったのが理由です。Endpoint Routing によってフレームワークから切り離されたルーティングが実現されました。
なので、これまで別々に用意されてきた CORS や認可周りは、共通のパイプライン上で処理が行えるようになりました。Endpoint Routing に関しては情報が少なく、Preview 4 の記事が比較的しっかりしてます。
ASP.NET Core 2.2 の Endpoint Routing とは異なり、パイプラインで明示的に UseRouting
と UseEndpoints
を呼び出す必要があります。それぞれのメソッドはルートのマッチングを行うタイミングと、実際にリクエストの処理を行うタイミングを表しています。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ルーティングに依存しない処理は UseRouting の前に書く if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); // ここでルートのマッチングが行われ、結果は HttpContext にセット app.UseRouting(); // 認証・認可はルーティングの結果が必要 app.UseAuthentication(); app.UseAuthorization(); // CORS もルーティングの結果が必要 app.UseCors(); // マッチング結果に従って各処理に振り分けられる app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapRazorPages(); }); }
よくあるパイプラインと同じなのでリクエストは上から順に実行されていき、一般的には UseEndpoints
でレスポンスが生成されて、リクエストとは逆の順番で実行されてクライアントに返っていきます。
ここまで理解できれば、Endpoint Routing はほぼ理解したことになります。
Status Code Page が動かなくなった
ASP.NET Core 3.0 への移行後に UseStatusCodePagesWithReExecute
を使って実装していたエラー画面が表示されなくなりました。これは HTTP ステータスコードごとにカスタムエラーページを実現する機能です。
移行後のアプリケーションでは存在しないページへのアクセス時に、ブラウザの 404 ページが表示されるようになってしまい、用意したエラーページは表示されなくなりました。
ここまで行ってきた Endpoint Routing の説明を踏まえると動かなくなった理由が分かると思いますが、原因は単純に UseStatusCodePagesWithReExecute
のパイプラインでの呼び出し位置が間違っていたことです。
リダイレクトの場合は問題ないのですが、パイプラインの再実行を行う場合はルーティングの前に呼び出しておく必要があります。ルーティング後に呼び出すと、実行されるエンドポイントが確定できません。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseHttpsRedirection(); app.UseStaticFiles(); // 指定した URL でパイプラインを再実行するので UseRouting の前に呼ぶ必要がある app.UseStatusCodePagesWithReExecute("/Error/Index", "?statusCode={0}"); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
正しく UseRouting
の前に呼び出すように修正すると、エラーページが表示されるようになりました。
最初の方は Endpoint Routing の挙動に慣れが必要な感じですが、これまで Core MVC のフィルタなどで独自に書いていた部分を、Middleware として ASP.NET Core 全体で使えるようになるのは良い感じです。
暫くすると公式ドキュメントも Endpoint Routing 対応に更新されるかと思います。