Why does Json.NET require System.Xml.Linq v5.0.5 for serialization of a simple object?
Asked Answered
I

1

23

I have the following object:

public class ProjectInfo
{
    public string ConnectionStringName { get; set; }
    public string DefaultEntityNamespace { get; set; }
    public string DefaultSharedNamespace { get; set; }
    public string DefaultTestNamespace { get; set; }
    public string SqlProviderName { get; set; }
}

Which I try to do a simple serialization of (in a VSIX project):

var settings = new ProjectInfo { ConnectionStringName = "SomeName" };
var json = JsonConvert.SerializeObject(settings);

which gives me:

An exception of type 'System.IO.FileNotFoundException' occurred in Newtonsoft.Json.dll but was not handled in user code

Additional information: Could not load file or assembly 'System.Xml.Linq, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

I've spent the last hour trying to figure out where the dependency comes from or why Json.NET tries to use that namespace. System.Xml.Linq is not referenced in any of my projects.

From the stack trace I can see:

   at Newtonsoft.Json.Converters.XmlNodeConverter.CanConvert(Type valueType)
   at Newtonsoft.Json.JsonSerializer.GetMatchingConverter(IList`1 converters, Type objectType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.InitializeContract(JsonContract contract)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(Type objectType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
   at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
   at Newtonsoft.Json.JsonConvert.SerializeObject(Object value)

..but why does it take that route?

Update

A simple test case also fails:

[Fact]
public void should_be_Able_to_Serialize_settings()
{
    JsonConvert.SerializeObject(new ProjectInfo {ConnectionStringName = "Arne"});
}

Update 2

This project has worked before. It also works on a colleague's computer. The only difference I can see is that I've upgraded to VStudio 2015 Update 1. (or that I've made a silly mistake somewhere). But I've also done a hard reset to the latest revision that my colleague uses.

Why does it try to reference v5.0.5 of System.Linq.Xml? Isn't v4.0.0 the standard one for .NET 4.5? Which version of .NET does v5.0.5 belong to?

(I've never had a similar problem with Json.NET before. Is it something with VStudio 2015 / .NET 4.5.2 / VSIX project?)

Update3

Here are the dependencies. They show that Json.NET tries to reference that exact version:

enter image description here

Update:

Json.NET reference in the project file:

<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=c70b2336aed9f731, processorArchitecture=MSIL">
  <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
  <Private>True</Private>
</Reference>

Edit 4:

My problem is that the extension fails to work as it tries to load an assembly that does not exist. From my understanding, v5.0.5 is a silverlight assembly. And I do not use silverlight.

I've tried to add an assembly redirect, but it doesn't seem to work.

<dependentAssembly>
  <assemblyIdentity name="System.Xml.Linq" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
  <bindingRedirect oldVersion="0.0.0.0-5.0.5.0" newVersion="4.0.0.0"/>
</dependentAssembly>
Indirection answered 1/12, 2015 at 20:50 Comment(24)
Can you show a short but complete program that demonstrates the problem? What's in settings?Aerophone
newtonsoft.json v7.0.1 via nugetIndirection
I got VStudio 2015 update 1Indirection
I can't reproduce this with a simple console app. Are you able to reproduce this in a regular project?Aerophone
I can't reproduce it either. Tried console app and unit test in class library. Will try in vsix.Richerson
Do you have the System.Xml.Linq assembly binding configured in your app.config/web.config? It could be you have an invalid binding configuration?Despicable
Json.NET has built-in converters for converting between JSON and XML, see Converting between JSON and XML. XmlNodeConverter is the class that does the conversion. In your traceback, it is being called to check if the object being serialized is a Linq to XML type. No idea why the library fails to load though; do you have it installed?Happen
Is the ProjectInfo class exactly as shown here - no other properties or fields, no attributes, etc. Or is there something subtle you may have not shown here?Richerson
Also, have you set anything via JsonConvert.DefaultSettings or just the defaults?Richerson
I can't reproduce it with a simple example either. that's the problem. I need to figure out what the dependency comes from so that I don't have to recreate the entire solution.Indirection
@MattJohnson: It's the exact class (only namespace differs). I had a IEnumerable it it before by removed it so that I've not included a linq expression by mistake. But the error is still there without that list.Indirection
@MattJohnson: I havent changed any default settings.Indirection
I suspect console applications are loading the dependency from the GAC, while the vsix project doesn't do that. Newtonsoft does have a dependency on it. i.imgur.com/xn6MVDx.pngDespicable
@Amy: I got no binding redirect.Indirection
Does version 5.0.5.0 not indicate a silverlight assembly? Its a long time since I developed silverlight applicationsOeildeboeuf
Can you check what is the framework selected in project properties? Is it .Net Framework Client Profile or normal frameworkStanhope
Well, I can tell you that XmlNodeConverter is one of the built-in converters that is tested for on every object deserialized with the default contract resolver. You can see it in the BuiltInConverters array here. That doesn't run for PORTABLE40, but other than that it's always going to be hit. Therefore you must be able to reference its dependencies. (That array is passed as the first parameter in the call to GetMatchingConverter, seen in your stack trace.)Richerson
What's the problem with adding a reference to System.Xml.Linq in your vsix project?Richerson
Are you possibly referencing an additional assembly that is a PCL? See this similar issue I foundRicherson
Can you share your project file (just the file) after you added the project reference? Something tells me you picked up the wrong asset from the NuGet package...Fai
@MattJohnson: The problem is that Visual Studio do not find v5.0.5 and therefore crashes with a TypeLoadException.Indirection
@JasonMalinowski: added the project reference to JSON.NETIndirection
@jgauffin: thanks...unfortunately that's what it should be. :-(Fai
Can you remove the nuget reference, remove the file leftovers and re-add via nuget? maybe 6.08 or 8.01-beta?Jordison
H
2

Json.NET uses System.Xml.Linq for converting json to xml.

You're going to be able to compile without a library's dependencies, as long as you don't reference any of the types in the dependencies. This is normal. I've had the same issue with NHibernate's Iesi.Collections dependency.

I looked in the Json.Net source code and the using statements for System.Xml.Linq are conditionalized for the .Net version. Are you and your colleague running the same .Net version? Did you recently change .Net on your machine?

What I would suggest is to completely remove NHibernate and any dependencies. Then install Json.Net with NuGet. NuGet will automatically add all dependencies and perform any needed assembly binding redirects.

Even if you don't want to use NuGet, run a diff and see what changes it makes so you can make the same.

Holoenzyme answered 6/3, 2016 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.