diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
index 8b49e92d..24b5d56b 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
@@ -519,5 +519,42 @@ Parameter name: arrayIndex")]
""o"": ""
\r\n
\r\n
\r\n
\r\n 444444444\r\n
\r\n
\r\n
\r\n
\r\n
""
}", o.ToString());
}
+
+ [Test]
+ public void ImplicitValueConversions()
+ {
+ JObject moss = new JObject();
+ moss["FirstName"] = new JValue("Maurice");
+ moss["LastName"] = new JValue("Moss");
+ moss["BirthDate"] = new JValue(new DateTime(1977, 12, 30));
+ moss["Department"] = new JValue("IT");
+ moss["JobTitle"] = new JValue("Support");
+
+ Console.WriteLine(moss.ToString());
+ //{
+ // "FirstName": "Maurice",
+ // "LastName": "Moss",
+ // "BirthDate": "\/Date(252241200000+1300)\/",
+ // "Department": "IT",
+ // "JobTitle": "Support"
+ //}
+
+
+ JObject jen = new JObject();
+ jen["FirstName"] = "Jen";
+ jen["LastName"] = "Barber";
+ jen["BirthDate"] = new DateTime(1978, 3, 15);
+ jen["Department"] = "IT";
+ jen["JobTitle"] = "Manager";
+
+ Console.WriteLine(jen.ToString());
+ //{
+ // "FirstName": "Jen",
+ // "LastName": "Barber",
+ // "BirthDate": "\/Date(258721200000+1300)\/",
+ // "Department": "IT",
+ // "JobTitle": "Manager"
+ //}
+ }
}
}
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
index d258a734..c5afb059 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
@@ -280,6 +280,8 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.IsTrue(JToken.DeepEquals(new JValue(float.MaxValue), (JValue)(float?)float.MaxValue));
Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.MaxValue));
Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null));
+
+ Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null));
}
[Test]
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs
index df1b0224..f661df44 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs
@@ -231,5 +231,59 @@ namespace Newtonsoft.Json.Tests.Serialization
TypeNameHandling = TypeNameHandling.Objects
});
}
+
+ public interface ICorrelatedMessage
+ {
+ string CorrelationId { get; set; }
+ }
+
+ public class SendHttpRequest : ICorrelatedMessage
+ {
+ public SendHttpRequest()
+ {
+ RequestEncoding = "UTF-8";
+ Method = "GET";
+ }
+ public string Method { get; set; }
+ public Dictionary Headers { get; set; }
+ public string Url { get; set; }
+ public Dictionary RequestData;
+ public string RequestBodyText { get; set; }
+ public string User { get; set; }
+ public string Passwd { get; set; }
+ public string RequestEncoding { get; set; }
+ public string CorrelationId { get; set; }
+ }
+
+ [Test]
+ public void DeserializeGenericTypeName()
+ {
+ string typeName = typeof(SendHttpRequest).AssemblyQualifiedName;
+
+ string json = @"{
+""$type"": """ + typeName + @""",
+""RequestData"": {
+""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
+""Id"": ""siedemnaĆcie"",
+""X"": ""323""
+},
+""Method"": ""GET"",
+""Url"": ""http://www.onet.pl"",
+""RequestEncoding"": ""UTF-8"",
+""CorrelationId"": ""xyz""
+}";
+
+ ICorrelatedMessage message = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
+ {
+ TypeNameHandling = TypeNameHandling.Objects
+ });
+
+ Assert.IsInstanceOfType(typeof(SendHttpRequest), message);
+
+ SendHttpRequest request = (SendHttpRequest) message;
+ Assert.AreEqual("xyz", request.CorrelationId);
+ Assert.AreEqual(2, request.RequestData.Count);
+ Assert.AreEqual("siedemnaĆcie", request.RequestData["Id"]);
+ }
}
}
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs
index 1f3a5a5b..2007b9e3 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerReader.cs
@@ -223,19 +223,9 @@ namespace Newtonsoft.Json.Serialization
if (_serializer.TypeNameHandling != TypeNameHandling.None)
{
- int delimiterIndex = qualifiedTypeName.IndexOf(',');
string typeName;
string assemblyName;
- if (delimiterIndex != -1)
- {
- typeName = qualifiedTypeName.Substring(0, delimiterIndex).Trim();
- assemblyName = qualifiedTypeName.Substring(delimiterIndex + 1, qualifiedTypeName.Length - delimiterIndex - 1).Trim();
- }
- else
- {
- typeName = qualifiedTypeName;
- assemblyName = null;
- }
+ ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
Type specifiedType;
try
diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
index 6bb948ba..38417e1a 100644
--- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
@@ -632,5 +632,48 @@ namespace Newtonsoft.Json.Utilities
return match.Invoke(args);
#endif
}
+
+ public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName)
+ {
+ int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName);
+
+ if (assemblyDelimiterIndex != null)
+ {
+ typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim();
+ assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim();
+ }
+ else
+ {
+ typeName = fullyQualifiedTypeName;
+ assemblyName = null;
+ }
+
+ }
+
+ private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName)
+ {
+ // we need to get the first comma following all surrounded in brackets because of generic types
+ // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+ int scope = 0;
+ for (int i = 0; i < fullyQualifiedTypeName.Length; i++)
+ {
+ char current = fullyQualifiedTypeName[i];
+ switch (current)
+ {
+ case '[':
+ scope++;
+ break;
+ case ']':
+ scope--;
+ break;
+ case ',':
+ if (scope == 0)
+ return i;
+ break;
+ }
+ }
+
+ return null;
+ }
}
}
\ No newline at end of file