How can I deserialize using TypeNameHandling.Objects in Json.NET Silverlight?

I get an exception when trying to deserialize in Silverlight. Test1 fails while Test2 succeeds. I also tried TypeNameAssemblyFormat for both Simple and Full, but I get the same results. Test2 can enable the build, why can't Json.NET?

Update:. I forgot to mention that the type I'm trying to deserialize is defined in another assembly from the silverlight collection, where deserialization occurs.

Both tests work in the non-silverlight .NET application.

How can I deserialize a json string with names?

private void Test1() { JsonSerializerSettings settings = new JsonSerializerSettings(); settings.TypeNameHandling = TypeNameHandling.Objects; string json1 = "{\"$type\":\"AmberGIS.NetworkTrace.DTO.NTPoint, NetworkTrace.DTO.Assembly\",\"X\":0.0,\"Y\":0.0,\"SpatialReference\":null}"; try { var n1 = JsonConvert.DeserializeObject<NTPoint>(json1, settings); //Error resolving type specified in JSON 'AmberGIS.NetworkTrace.DTO.NTPoint, NetworkTrace.DTO.Assembly'. //Could not load file or assembly 'NetworkTrace.DTO.Assembly, Culture=neutral, PublicKeyToken=null' or one of its dependencies. //The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest. //(Exception from HRESULT: 0x80131053) } catch (Exception ex) { while (ex != null) { Debug.WriteLine(ex.Message); ex = ex.InnerException; } } } 

This test2 succeeds:

 private void Test2() { var pnt1 = new AmberGIS.NetworkTrace.DTO.NTPoint(); Debug.WriteLine(pnt1.GetType().AssemblyQualifiedName); // "AmberGIS.NetworkTrace.DTO.NTPoint, NetworkTrace.DTO.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" string fullName = "AmberGIS.NetworkTrace.DTO.NTPoint, NetworkTrace.DTO.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"; var t = Type.GetType(fullName); var pnt2 = Activator.CreateInstance(t) as NTPoint; } 
+7
source share
3 answers

Try adding settings to JsonConvert.DeserializeObject<T>(json, Settings) , where Settings:

 new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full } 
+6
source

I solved the problem by downloading the source code for Json.NET 4.0r2 and adding 2 lines of hack code to DefaultSerializationBinder.cs, as shown below. This probably won't work for the strong named builds. Silverlight does not have an appdomain scan method for loaded assemblies, see here .

 #if !SILVERLIGHT && !PocketPC // look, I don't like using obsolete methods as much as you do but this is the only way // Assembly.Load won't check the GAC for a partial name #pragma warning disable 618,612 assembly = Assembly.LoadWithPartialName(assemblyName); #pragma warning restore 618,612 #else // **next 2 lines are my hack** ... string fullName = String.Format("{0}, {1}, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",typeName,assemblyName); return Type.GetType(fullName); assembly = Assembly.Load(assemblyName); #endif 
+2
source

I post my solution here, which does not require a Json.NET modification:

The problem is that the following line is not enough for Silverlight:

 string json1 = "{\"$type\":\"AmberGIS.NetworkTrace.DTO.NTPoint, NetworkTrace.DTO.Assembly\" ... }"; 

It is required:

 string json1 = "{\"$type\":\"AmberGIS.NetworkTrace.DTO.NTPoint, NetworkTrace.DTO.Assembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null \", ...}"; 

So, my way to include this in JSON (in my case, JSON cannot be changed since it appeared from the server and JSON.net was not created) is to manually modify JSON by iterating over all (nested) objects and inserting information about assembly:

 string json = <some json you want fixed> Type type = <the target type you want> JObject jsonObject = JObject.parse (json); jsonObject["$type"] = type.FullName + ", " + type.Assembly.FullName; json = jsonObject.ToString(Formatting.None, null); 

Then you can deserialize as usual using

 JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }; var n1 = JsonConvert.DeserializeObject<NTPoint>(json, settings); 
+1
source

All Articles