-Fixed generic type deserialization with type name tracking enabled

This commit is contained in:
JamesNK
2009-07-30 08:59:07 +00:00
parent c770fe5e7c
commit 7f0bafeea7
5 changed files with 137 additions and 11 deletions
@@ -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.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(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]
@@ -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<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)
{
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
@@ -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;
}
}
}