This is more of a tech support question, but the newtonsoft.com website says stackoverflow is the best place to ask questions.
I have a string that was serialized with 6.0.3, and fails to deserialize with 6.0.8. It throws InvalidCastException. When I downgrade to 6.0.3, it deserializes fine; when I upgrade again to 6.0.8, the exception is repeatable.
Edit:
Rather than post the actual string, which is 10KB long and contains sensitive information, I was able to create a simple reproducible test case that demonstrates the problem.
The line that throws exception is:
this.SomeStrings = (string[])infoEnum.Current.Value;
The InvalidCastException says "Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'System.String[]'"
As mentioned in the comments below, I serialized an instance of FooClass with 6.0.3, and then hard-coded the string into the asdf() method and attempt to deserialize. Deserialization succeeds on 6.0.3, and fails with InvalidCastException on 6.0.8.
Obviously, in the trivial repro case below, there is no point in doing ISerializable on FooClass, but in real life I have a need to use ISerializable in a complex data type that serializes and deserializes itself as a string array; the following is just to academically illustrate reproduction of the bug behavior.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.Runtime.Serialization;
namespace CBClasses
{
[Serializable]
public class FooClass : ISerializable
{
public string[] SomeStrings { get; set; }
public FooClass() { }
protected FooClass(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException();
SerializationInfoEnumerator infoEnum = info.GetEnumerator();
while (infoEnum.MoveNext()) {
SerializationEntry entry = infoEnum.Current;
switch (entry.Name) {
case "SomeStrings":
this.SomeStrings = (string[])infoEnum.Current.Value;
break;
default:
throw new SerializationException("Deserialization failed on unhandled member '" + entry.Name + "'");
}
}
}
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("SomeStrings", this.SomeStrings, this.SomeStrings.GetType());
}
}
public class NewtonsoftDebugTest
{
private static JsonSerializerSettings settings = new JsonSerializerSettings() {
TypeNameHandling = TypeNameHandling.All,
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
};
public static void asdf()
{
/* FooClass foo = new FooClass() { SomeStrings = new string[0] };
* string serializedBy603 = JsonConvert.SerializeObject(foo, settings);
* Resulted in:
*
* {
* "$id": "1",
* "$type": "CBClasses.FooClass, CBClasses",
* "SomeStrings": {
* "$type": "System.String[], mscorlib",
* "$values": []
* }
* }
*
* Now hard-coded below:
*/
string serializedBy603 =
"{\n" +
" \"$id\": \"1\",\n" +
" \"$type\": \"CBClasses.FooClass, CBClasses\",\n" +
" \"SomeStrings\": {\n" +
" \"$type\": \"System.String[], mscorlib\",\n" +
" \"$values\": []\n" +
" }\n" +
"}\n";
FooClass deserialized = (FooClass)JsonConvert.DeserializeObject(serializedBy603, settings);
System.Diagnostics.Debugger.Break();
}
}
}
object {Newtonsoft.Json.Linq.JObject}and it has value{ "$type": "System.String[], mscorlib", "$values": [] }... Maybe the problem is actually converting String[] to string[]? ... No - I'm sure the problem is casting Newtonsoft.Json.Linq.JObject to string[], even though the value inside the JObject clearly indicates it should be a String[]