Проблема Newtonsoft.Json.dll при использовании нескольких проектов
Я вижу действительно странное поведение, которое мне не удалось исправить, связанное со ссылками на Newtonsoft.Json.dll. У меня есть пример решения, созданного со следующими проектами:
- JsonProblem.Core
- JsonProblem.CauseProblem (ссылается на JsonProblem.Core)
- JsonProblem.Web (ссылается на JsonProblem.Core и JsonProblem.CauseProblem)
В JsonProblem.Core и JsonProblem.Web я добавил пакет NuGet "Microsoft ASP.NET Web API 2.2". В JsonProblem.Core я создал веб-API. Если я собираю JsonProblem.Core и запускаю страницу из JsonProblem.Web, все работает как положено.
Теперь, если я собираю JsonProblem.CauseProblem и пытаюсь просмотреть страницу в JsonProblem.Web, я получаю следующую ошибку.
Не удалось загрузить файл или сборку 'Newtonsoft.Json' или одну из ее зависимостей. Определение манифеста обнаруженной сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)
Если я пересоберу JsonProblem.Core, ошибка исчезнет. И снова, если я собираю JsonProblem.CauseProblem без сборки JsonProblem.Core впоследствии (даже если JsonProblem.CauseProblem зависит от JsonProblem.Core), я получаю ошибку. Каким-то образом сборка JsonProblem.CauseProblem приводит к тому, что версия 4.5.11 Newtonsoft.Json копируется в каталог bin JsonProblem.Web, перезаписывая версию 6.0.3. Я почти уверен, что у меня правильно настроены перенаправления привязки, как у меня в файле JsonProblem.Web web.config и в файлах app.config для JsonProblem.Core и JsonProblem.CauseProblem:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
Так что я в растерянности относительно причины этого странного поведения. Я воспроизвел это в 2 проектах. Кажется, что перенаправления привязки игнорируются, когда я собираю JsonProblem.CauseProblem. Я могу обойти это, но я обеспокоен тем, что любая ошибка или функция, вызывающая такое поведение, может изменять другие ссылки в фоновом режиме, что может вызвать проблемы в будущем.
РЕДАКТИРОВАТЬ - как предположил Тиззи, я использовал инструмент fuslogvw. Вот что было сгенерировано в журнале. Однако я не уверен, как это интерпретировать, потому что журнал не сообщает мне, что происходит во время сборки, чтобы перезаписать версию Newtonsoft.Json.dll в каталоге веб-сайта моего приложения.
The operation failed.
Bind result: hr = 0x80131040. No description available.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable C:\Program Files\IIS Express\iisexpress.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: DisplayName = Newtonsoft.Json
(Partial)
WRN: Partial binding information was supplied for an assembly:
WRN: Assembly Name: Newtonsoft.Json | Domain ID: 5
WRN: A partial bind occurs when only part of the assembly display name is provided.
WRN: This might result in the binder loading an incorrect assembly.
WRN: It is recommended to provide a fully specified textual identity for the assembly,
WRN: that consists of the simple name, version, culture, and public key token.
WRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue.
LOG: Appbase = file:///C:/Users/John/Desktop/JsonProblem/JsonProblem.Web/
LOG: Initial PrivatePath = C:\Users\John\Desktop\JsonProblem\JsonProblem.Web\bin
LOG: Dynamic Base = C:\Users\John\AppData\Local\Temp\Temporary ASP.NET Files\vs\3661babd
LOG: Cache Base = C:\Users\John\AppData\Local\Temp\Temporary ASP.NET Files\vs\3661babd
LOG: AppName = 3b3fd45
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Users\John\Desktop\JsonProblem\JsonProblem.Web\web.config
LOG: Using host configuration file: C:\Users\John\Documents\IISExpress\config\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///C:/Users/John/AppData/Local/Temp/Temporary ASP.NET Files/vs/3661babd/3b3fd45/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Users/John/AppData/Local/Temp/Temporary ASP.NET Files/vs/3661babd/3b3fd45/Newtonsoft.Json/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Users/John/Desktop/JsonProblem/JsonProblem.Web/bin/Newtonsoft.Json.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\John\Desktop\JsonProblem\JsonProblem.Web\bin\Newtonsoft.Json.dll
LOG: Entering download cache setup phase.
LOG: Assembly Name is: Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
LOG: A partially-specified assembly bind succeeded from the application directory. Need to re-apply policy.
LOG: Using application configuration file: C:\Users\John\Desktop\JsonProblem\JsonProblem.Web\web.config
LOG: Using host configuration file: C:\Users\John\Documents\IISExpress\config\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Redirect found in application configuration file: 4.5.0.0 redirected to 6.0.0.0.
LOG: Post-policy reference: Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
LOG: GAC Lookup was unsuccessful.
LOG: The post-policy assembly reference requires probing again.
LOG: Attempting download of new URL file:///C:/Users/John/AppData/Local/Temp/Temporary ASP.NET Files/vs/3661babd/3b3fd45/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Users/John/AppData/Local/Temp/Temporary ASP.NET Files/vs/3661babd/3b3fd45/Newtonsoft.Json/Newtonsoft.Json.DLL.
LOG: Attempting download of new URL file:///C:/Users/John/Desktop/JsonProblem/JsonProblem.Web/bin/Newtonsoft.Json.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\Users\John\Desktop\JsonProblem\JsonProblem.Web\bin\Newtonsoft.Json.dll
LOG: Entering download cache setup phase.
LOG: Assembly Name is: Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed
WRN: Comparing the assembly name resulted in the mismatch: Major Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Setup failed with hr = 0x80131040.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
2 ответа
У меня было то же поведение, что и в приведенном выше описании проблемы, за исключением того, что когда я перестраивал свою библиотеку классов (т.е. JsonProblem.Core), она вытягивала Newtonsoft.dll 4.5.11, даже если эта библиотека классов не имела прямой ссылки или пакета Nuget это указывало на ссылку на NewtonSoft.
В том, что можно считать ошибкой Visual Studio 2015, перестройка библиотеки классов копирует библиотеки DLL с невидимыми ссылками в ссылки на папки bin проекта (в данный момент не создаются), перезаписывает библиотеки DLL в ссылках на проекты, ломая их.
IOW, например, построить проект Y (ссылаясь на JsonProblem.Core), очевидный успех. Создайте проект X (см. JsonProblem.Core), который нарушает проект Y. Создайте проект Y, и теперь это нарушает проект X. Бесконечный цикл: while( sane) { build(); }
В моем случае единственными сторонними библиотеками, на которые я ссылался в этой библиотеке, были Gibraltar.Agent и Gibraltar.Agent.Web.Mvc (которые не сообщали о зависимости от NewtonSoft. Щелкните правой кнопкой мыши по ним в разделе "Ссылки проекта" и выберите "Найти код, зависящий от этот модуль "показал, что мне не нужно ссылаться на 2-й.
Я удалил Gibraltar.Agent.Web.Mvc в Nuget, и все проблемы ушли. Два дня сердечной боли DLL Ада закончились.
Вы можете иметь дело с несколькими различными сценариями здесь. Я бы посоветовал вам использовать инструмент fuslogvw, чтобы показать вам, какую dll он пытается загрузить и где ее ищет. Возможно, здесь скрывается другая проблема с зависимостями, поскольку перенаправление привязки сборки выглядит корректно на поверхности. Инструмент fuslogvw просто позволит вам увидеть поведение привязки сборки и то, что происходит. Это здорово иметь при сборке проблем с привязкой.