経緯
とあるプロジェクトで、半年ほど前に作成したASP.NET MVCのプロジェクトを改修してデプロイしたら
下記のようなエラーを吐いて、Webページが正常に開けなくなってしまいました。
System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
web.configを見ると確かにSystem.RuntimeのDependencyが書かれていました。
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="B03F5F7F11D50A3A" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0"/>
</dependentAssembly>
しかも、よく調べると このライブラリは.Net Frameworkではなく、.NET Standard。
差分を見ると、今回の改修で混入したことは間違いありません。
根本の原因はNugetのバグらしい
根本原因については、NugetのGitHubにIssueが挙がっていました。
PackageRef project opt-in technique #4488
どうやらNugetで依存する.Net Standardライブラリを取ってくるときに、ライブラリの場所が分からなくなってしまうらしい。
Visual Studio 2017で.NET Core プロジェクトが project.jsonではなく、 MSBuild/csproj 形式に移行されたことが原因かもしれないですね。
(勉強不足で変なことを言っていたら申し訳ありません。)
なぜ .Net Standardライブラリが降臨したのか
修正前のプロジェクトでは、WindowsAzure.Storageの8.0.1を参照していました。
https://www.nuget.org/packages/WindowsAzure.Storage/8.0.1
今回の改修では、ついでにストレージクライアントも最新の8.1.0に上げようとしていました。
https://www.nuget.org/packages/WindowsAzure.Storage/8.1.0
両者のdependenciesを比較するとMicrosoft.Data.Services.Clientが (>= 5.7.0) から (>= 5.8.2) に変わっています。
さらに5.8.2のdependenciesをみると
.NETStandard 1.1
Microsoft.Data.OData (= 5.8.2)
System.ComponentModel.EventBasedAsync (>= 4.0.11)
System.Dynamic.Runtime (>= 4.0.0)
System.Linq.Queryable (>= 4.0.0)
System.Net.Requests (>= 4.0.11)
とあり、.NET Standrdライブラリが参照に追加されていました。これが理由でした。
参考
https://www.nuget.org/packages/Microsoft.Data.Services.Client/5.8.2
やっぱりライブラリのアップデートは慎重に
NuGetのGitHubに対策は書いてありますが、csprojファイルを手動で書き換えなければならず、正直言って時間が経ったり、担当者が変わったりしたら忘れさられてしまいそうです。
今回のプロジェクトでは、そもそもWindowsAzure.Storageのアップデートは必須ではないため、バージョンを戻すという選択をしました。
やっぱりライブラリのアップデートは慎重に行うべきですね。