🧩

.NET Frameworkで発生した『System.Net.Http が見つからない』問題を解決した話

に公開

はじめに

今回は、.NET Framework プロジェクトで発生した
System.Net.Http のアセンブリ競合問題をどのように解決したかを紹介します。

🔥 発生したエラー

.NET Frameowrk4.7で開発していたアプリケーションを.NET Framework4.7.2に上げ、MySqlConnector パッケージを更新すると、アプリ実行時に次のエラーが発生しました。

ファイルまたはアセンブリ 'System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'、
またはその依存関係の 1 つが読み込めませんでした。
指定されたファイルが見つかりません。

一見「System.Net.Http.dll が無い」と言われていますが、実際には アセンブリのバージョン競合 が原因でした。


背景

  • ターゲットを .NET Framework 4.7 から .NET Framework 4.7.2に変更
  • 以前使用していた MySqlConnector は 0.56
  • バージョンアップして MySqlConnector 2.x 系を導入した

すると内部で使用される System.Net.Http の依存関係が変わり、異なるバージョンの DLL を読み込もうとして混乱が起こりました。


最初の試み(失敗)

NuGet で System.Net.Http を追加し、Web.config にバージョンリダイレクトを追加しました。

Web.config
<dependentAssembly>
  <assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.3.4.0" newVersion="4.3.4.0" />
</dependentAssembly>

この記述は、System.Net.HttpのVersion 0.0.0.0~4.3.4.0が要求されたら、newVersionで指定した 4.3.4.0 にリダイレクトする指定です。

しかし、今度は以下のようなエラーに変化。

ファイルまたはアセンブリ 'System.Net.Http, Version=4.3.4.0' が見つかりません。

つまり、別のバージョン競合を引き起こしてしまったのです。


原因の本質

.NET Framework 4.7 以降では、
System.Net.Http はフレームワーク本体(GAC)に統合されています。

ところが、NuGet 経由で追加した System.Net.Http(4.3.x)は
同名の別 DLL(.NET Standard 用)で、GAC のものと競合してしまいます。

その結果、

Version 4.0.0.0(GAC) vs Version 4.2.0.0(NuGet)

の衝突が起こり、ランタイムで「見つからない」と言われてしまったわけです。


最終的な解決方法

結論から言うと、NuGet 版 System.Net.Http を削除し、フレームワーク組み込みのものを使う ことで解決しました。

1. NuGet の System.Net.Http を削除

Visual Studio の「ソリューション エクスプローラー」で:

→ 参照
   → System.Net.Http

を右クリックして「削除」。

2. csproj を以下のように修正

<Reference Include="System.Net.Http" />

👉 HintPath や Version の指定は 一切書かないこと。 これでフレームワーク標準の System.Net.Http が参照されます。


3. 不要な DLL をクリーン

bin フォルダに System.Net.Http.dll が残っていたら削除します。

dir bin\System.Net.Http.dll

存在する場合は手動で削除してから再ビルド。


4. MySqlConnector は安定版 0.57.0 を採用

ここは悩んだところなのですが、できるだけこれまで利用していたバージョンとの差異が少ない、0.57.0 採用することにしました。
このバージョンなら、.NET Framework 4.7.1~4.8 で安定動作します。

Visual StudioのNuGetパッケージマネージャでMySqlConnectorのバージョンを 0.57.0 に更新します。

これで以下のようのファイルが更新されるはずです。

package.config
  <package id="MySqlConnector" version="0.57.0" targetFramework="net472" />
.csproj
<Reference Include="MySqlConnector, Version=0.57.0.0, Culture=neutral, PublicKeyToken=d33d3e53aa5f8c92, processorArchitecture=MSIL">
  <HintPath>..\packages\MySqlConnector.0.57.0\lib\net471\MySqlConnector.dll</HintPath>
</Reference>

5. 依存アセンブリのリダイレクト設定

Web.config
<dependentAssembly>
  <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe"
                    publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-4.0.6.0"
                   newVersion="4.0.6.0" />
</dependentAssembly>

これで System.Runtime まわりの警告も消えました。

ちなみに、このプロジェクトでは、System.Runtime.CompilerServices.Unsafeはバージョン 4.7.1 を利用しています。


結果

  • ✅ ビルド成功
  • ✅ 実行時エラーなし
  • ✅ MySqlConnector も正常動作

最終的に .NET Framework 4.7.2 の標準 System.Net.Http を利用する構成で安定しました。


まとめ

やること 理由
NuGet の System.Net.Http を削除 フレームワーク版と競合するため
csproj に <Reference Include="System.Net.Http" /> のみ残す GAC 参照を明示
bin の System.Net.Http.dll を削除 古い DLL の残骸防止
MySqlConnector 0.57.0 を使用 .NET 4.7.2 対応の安定版

.NET/.NET Frameworkのパッケージのバージョンを上げた時は、こういったパッケージのバージョン不一致で悩まされることもありますので、何かの参考になればと思い、この記事を公開しています。


補足:パッケージのバージョンはどうやって選ぶのか?

この補足では、利用するパッケージのバージョンはどうやって選ぶのかについてまとめてみました。.NET Frameworkを前提にしていますが、考え方は.NETにおいても参考になると思います。

重要なのは「パッケージがどのターゲットフレームワーク用のアセンブリを含んでいるか」です。例えば、今回問題になった MySqlConnector はバージョンによってサポートするターゲットが異なり、それが System.Net.Http などの依存関係に影響します。

確認方法(確実で簡単)

  • nuget.org の MySqlConnector パッケージページを開く(使用するバージョンを選ぶ)。
    「依存関係(Dependencies)」や「Files」タブで lib フォルダの中身(net471 / netstandard2.0 / net8.0 など)を確認する。
  • ローカルで確認する場合は、packages.config を使っているなら packages<MySqlConnector>.<version>\lib\ の下を見れば、どのターゲット向け DLL が入っているか分かる。

よくあるマッピング例(一般論)

  • net4xx / net47x: .NET Framework 向けアセンブリ。フレームワークの API を直接利用。
  • netstandard2.0: .NET Framework 4.6.1 以降や .NET Core / .NET 5+ で利用可能な互換バイナリ。ただし netstandard ビルドは System.Net.Http などの依存が netstandard 用のアセンブリ参照になるため、.NET Framework 実行環境では追加のパッケージ参照や bindingRedirect が必要になる場合がある。
  • net8.0 / net9.0 等: .NET (Core) 向け。フレームワークの GAC 概念は無い。

影響例

  • MySqlConnector が netstandard2.0 ビルドを提供しており、プロジェクトが .NET Framework 4.7.2 の場合、NuGet によって netstandard2.0 用アセンブリ(およびその依存)が解決されます。
  • その結果、プロジェクトに組み込まれた System.Net.Http(GAC のもの)と、パッケージ経由で解決された System.Net.Http(netstandard 用)が競合することがあります。これが今回の問題の典型パターンです。

対処の基本

  • 可能なら、.NET Framework 向けのターゲット(例: lib\net471 等)を提供する MySqlConnector のバージョンを選ぶ。話がややこしくなるので、深入りしませんが、こうすることで、netstandard 経由で起きる System.Net.Http の競合は避けやすくなります。

  • もしパッケージが netstandard のみを提供する場合は、csproj の参照管理(HintPath / CopyLocal)や web.config の bindingRedirect、あるいは packages.config → PackageReference 移行で解決しやすくなる場合があります。(HintPath,CopyLocalについての説明は省略します)

  • どのバージョンを選ぶかは「ターゲットフレームワーク」「テスト済みの安定版」「互換性要件」で決めることになると思います。今回の記事では互換性が高い 0.57.0 を採用しましたが、利用の際は nuget.org の release notes を確認してください。

GitHubで編集を提案
株式会社ジード テックブログ

Discussion