-Fixed generic type deserialization with type name tracking enabled
This commit is contained in:
@@ -519,5 +519,42 @@ Parameter name: arrayIndex")]
|
|||||||
""o"": ""<div class='s1'>\r\n <div class='avatar'> \r\n <a href='asdf'>asdf</a><br />\r\n <strong>0</strong>\r\n </div>\r\n <div class='sl'>\r\n <p>\r\n 444444444\r\n </p>\r\n </div>\r\n <div class='clear'>\r\n </div> \r\n</div>""
|
""o"": ""<div class='s1'>\r\n <div class='avatar'> \r\n <a href='asdf'>asdf</a><br />\r\n <strong>0</strong>\r\n </div>\r\n <div class='sl'>\r\n <p>\r\n 444444444\r\n </p>\r\n </div>\r\n <div class='clear'>\r\n </div> \r\n</div>""
|
||||||
}", o.ToString());
|
}", 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"
|
||||||
|
//}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(float.MaxValue), (JValue)(float?)float.MaxValue));
|
||||||
Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.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.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null));
|
||||||
|
|
||||||
|
Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -231,5 +231,59 @@ namespace Newtonsoft.Json.Tests.Serialization
|
|||||||
TypeNameHandling = TypeNameHandling.Objects
|
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<string, string> Headers { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public Dictionary<string, string> 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<ICorrelatedMessage>(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"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -223,19 +223,9 @@ namespace Newtonsoft.Json.Serialization
|
|||||||
|
|
||||||
if (_serializer.TypeNameHandling != TypeNameHandling.None)
|
if (_serializer.TypeNameHandling != TypeNameHandling.None)
|
||||||
{
|
{
|
||||||
int delimiterIndex = qualifiedTypeName.IndexOf(',');
|
|
||||||
string typeName;
|
string typeName;
|
||||||
string assemblyName;
|
string assemblyName;
|
||||||
if (delimiterIndex != -1)
|
ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName);
|
||||||
{
|
|
||||||
typeName = qualifiedTypeName.Substring(0, delimiterIndex).Trim();
|
|
||||||
assemblyName = qualifiedTypeName.Substring(delimiterIndex + 1, qualifiedTypeName.Length - delimiterIndex - 1).Trim();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
typeName = qualifiedTypeName;
|
|
||||||
assemblyName = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type specifiedType;
|
Type specifiedType;
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -632,5 +632,48 @@ namespace Newtonsoft.Json.Utilities
|
|||||||
return match.Invoke(args);
|
return match.Invoke(args);
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user