3

I am seeing some really odd behavior that I have not been able to correct related to references for Newtonsoft.Json.dll. I have a sample solution set up with the following projects:

  • JsonProblem.Core
  • JsonProblem.CauseProblem (references JsonProblem.Core)
  • JsonProblem.Web (references JsonProblem.Core and JsonProblem.CauseProblem)

In JsonProblem.Core and JsonProblem.Web I have added the "Microsoft ASP.NET Web API 2.2" NuGet package. In JsonProblem.Core I have created a web api. If I build JsonProblem.Core and run a page from JsonProblem.Web everything works as expected.

Now if I build JsonProblem.CauseProblem and try to view a page in JsonProblem.Web, I get the following error.

Could not load file or assembly 'Newtonsoft.Json' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

If I rebuild JsonProblem.Core the error goes away. And again if I build JsonProblem.CauseProblem without building JsonProblem.Core afterward (even though JsonProblem.CauseProblem depends on JsonProblem.Core) I get the error. Somehow the build of JsonProblem.CauseProblem is causing version 4.5.11 of Newtonsoft.Json to get copied to the JsonProblem.Web bin directory, overwriting version 6.0.3. I'm pretty sure I have binding redirects setup correctly, as I have the following in the JsonProblem.Web web.config and in the app.config files for JsonProblem.Core and 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>

So I am at a loss as to the cause of this strange behavior. I have reproduced it in 2 projects. It seems that the binding redirects are ignored when I build JsonProblem.CauseProblem. I can work around it, but I'm concerned that whatever bug or feature is causing this behavior may be altering other references in the background that might cause problems down the line.


EDIT - as tizzy suggested I used the fuslogvw tool. Here is what was generated in the log. I'm not sure how to interpret this, however, because the log does not tell me what happens at build time to overwrite the version of Newtonsoft.Json.dll in my the app's website directory.

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.
John
  • 772
  • 7
  • 17
  • Yes, I am adding the WebApi packages via NuGet, which also adds Newtonsoft.Json as a dependency. – John Jul 16 '14 at 19:08
  • I had struggled same issue before. After update web api 2.2 I have removed old newtonsoft dll from another proejcts and installed new one from nuget and I have removed nuget cache. – Ozan Yurtseven Jul 16 '14 at 19:18
  • I'm sure I had the same problem before (and it was also with Newtonsoft.Json) when using NuGet. I'll try to ask my colleagues. Meanwhile, can't you play with NuGet packages to get the exact same version of Newtonsoft.Json in both projects? – Arseni Mourzenko Jul 16 '14 at 20:59
  • I added the WebApi nuget package to JsonProblem.CauseProblem, which also adds Newtonsoft.Json as a dependency. Now when I build JsonProblem.CauseProblem the problem is gone. This adds references that I don't want or need to the JsonProblem.CauseProblem project, however. I removed the references and left the NuGet package and things continued to work, but I feel like I am working around a bug in Visual Studio here. This means that I have to add all NuGet packages to every project in my solution, regardless of whether a project needs a particular NuGet package, and that just feels like a hack. – John Jul 17 '14 at 17:26
  • Any updates for this issue? – Fabio Aug 01 '14 at 20:30
  • Fabio - unfortunately no. I plan on updating to VS 2013 update 3 today to see if that helps. Will post pack if it resolves the issue, but I gave up trying to fix it because nothing seemed to work. – John Aug 05 '14 at 15:01

2 Answers2

1

I had the exact same behavior as the above problem description, except that when I rebuilt my class library (i.e. JsonProblem.Core), it would pull in Newtonsoft.dll 4.5.11, even though this class library had no direct reference or Nuget package that indicated a reference to NewtonSoft.

In what could be considered a Visual Studio 2015 bug, the class library rebuild copies the invisibly referenced DLLs into referencing project bin folders (not currently being built), overwriting the DLLs in referencing projects, breaking them.

IOW, for example, build project Y (referencing JsonProblem.Core), apparent success. Build project X (ref to JsonProblem.Core) which breaks project Y. Build Project Y and now this breaks Project X. Infinite loop: while( sane ) { build(); }

In my case, the only 3rd party libraries that I was referencing in this library were Gibraltar.Agent and Gibraltar.Agent.Web.Mvc (which reported no dependency on NewtonSoft. Right clicking on these in project References and selecting "Find Code Dependent on this module" revealed that I didn't need to reference the 2nd one.

I uninstalled Gibraltar.Agent.Web.Mvc in Nuget, and all problems went away. Two days of DLL Hell heartache have ended.

Gunnar
  • 339
  • 2
  • 13
0

You may be dealing with a handful of different scenarios here. My advice to you would be to use the fuslogvw tool to show you which dll it's trying to load, and where it's looking for it. It is possible that there is another dependency problem that is being masked here, since your assembly binding redirect looks correct on the surface. The fuslogvw tool will just allow you to see the assembly binding behavior, and what's happening. It's great to have for assembly binding issues.

trmiller
  • 183
  • 5
  • Thanks for the feedback, I posted content from the log above. I'm still at a loss as to why building the JsonProblem.CauseProblem project causes the Newtonsoft.Json.dll assembly in JsonProblem.Web to be overwritten by the assembly from the GAC. – John Jul 16 '14 at 19:07