しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET Core 2.1 の暗黙的なバージョンには注意

適当に Twitter を眺めていると、モリス先輩が ASP.NET Core Module 周りのエラーではまってそうだったので、また鰻を奢ってもらうために助けることにしました。

曰く、Visual Studio のテンプレートから作成して、App Service にデプロイしただけで発生するとか。

確かに同じようにテンプレートから作成して、App Service にデプロイしたところ HTTP Error 502.5 - Process Failure が返ってきて、アプリケーションは正しく起動してくれませんでした。

ANCM が原因で落ちる時は、そもそもランタイムのバージョンが間違っていてプロセスを起動できないというケースぐらいしかないです。なので、原因は ASP.NET Core 2.1.1 がリリースされたことにあります。

App Service のランタイムは Microsoft 管理なので、大体は RTM リリースと同タイミングで VM にインストールされるのですが、今回の 2.1.1 は少しタイムラグが発生したようです。*1

とはいえ 2.1.0 はインストールされているはずなので、これまでの場合は明示的に ASP.NET Core のバージョンを変更しない限り問題なかったのですが、2.1 からは SDK から暗黙的にバージョンが選択される機能が追加されています。

When the version is not specified, an implicit version is specified by the SDK, that is, Microsoft.NET.Sdk.Web. We recommend relying on the implicit version specified by the SDK and not explicitly setting the version number on the package reference.

Microsoft.AspNetCore.App metapackage for ASP.NET Core 2.1 and later | Microsoft Docs

具体的には PackageReferenceVersion を無指定に出来ます。Visual Studio から新規作成すると、この状態でプロジェクトが生成されます。

f:id:shiba-yan:20180625011154p:plain:w550

ソリューションエクスプローラーからバージョンを確認すると、2.1.1 になっていることがわかります。

f:id:shiba-yan:20180625011208p:plain:w400

このため 2.1.1 がインストールされていない App Service にランタイムを含まないポータブルな形でデプロイを行った結果、必要なバージョンのアセンブリが読み込めずエラーになったという話です。

とりあえずの対応方法としては App Service でインストールされているバージョンを明示的に指定すれば良いのですが、ドキュメントにはメタパッケージの暗黙的なバージョンに関して以下のような記述もあります。

The implicit version is set to major.minor.0 for portable apps. The shared framework roll-forward mechanism will run the app on the latest compatible version among the installed shared frameworks. To guarantee the same version is used in development, test, and production, ensure the same version of the shared framework is installed in all environments. For self contained apps, the implicit version number is set to the major.minor.patch of the shared framework bundled in the installed SDK.

Microsoft.AspNetCore.App metapackage for ASP.NET Core 2.1 and later | Microsoft Docs

ポータブルなアプリに関しては暗黙的なバージョンとして major.minor.0 がセットされるとあります。

なので、ドキュメント通りであれば Microsoft.AspNetCore.App の暗黙的なバージョンは 2.1.0 になると思うのですが、実際にはそうはなってませんでした。理由はよくわかりません。

Docker を使っている環境でも起こり得る問題なので、バージョン管理は気を付けましょう。

GitHub では Issue が乱立されるような状態になっていて、中々に影響範囲が広い問題だったようです。

次に ASP.NET Core 2.1.2 や 2.2 がリリースされたときにも同じような問題が発生するかも知れませんので、暗黙的なバージョンに関してはもうちょっと慎重になった方が良さそうです。

*1:2.1.0 の時も Japan East / West は遅かったので、時差の関係もあるっぽい?