以下示例说明了Json.NET类型处理的一个基本缺陷:
List<object> items = new List<object>() {Guid.NewGuid(),DateTime.Now};
var settings = new JsonSerializerSettings() { TypeNameHandling=TypeNameHandling.All };
var json = JsonConvert.SerializeObject<List<object>>(value,settings);
产生以下JSON:
{"$type":"System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib","$values":["9d7aa4d3-a340-4cee-baa8-6af0582b8acd","2014-07-28T21:03:17.1287029-04:00"]}
如您所见,列表项已丢失其类型信息。反序列化相同的JSON将导致列表只包含字符串。
此问题之前曾在codeplex上报告并且已经完全关闭,说明包含类型信息会使JSON过于混乱。我很惊讶我们没有给出单独的选项来包括原始类型信息,因为往返一致性被破坏了。
https://json.codeplex.com/workitem/23833
我希望数据返回时带有与之相同的类型信息。 有没有人有任何建议或解决方法可以解决这种不良行为?
谢谢,
克里斯
答案 0 :(得分:15)
以下是使用自定义JsonConverter
的解决方案:
public sealed class PrimitiveJsonConverter : JsonConverter
{
public PrimitiveJsonConverter()
{
}
public override bool CanRead
{
get
{
return false;
}
}
public override bool CanConvert(Type objectType)
{
return objectType.IsPrimitive;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
switch (serializer.TypeNameHandling)
{
case TypeNameHandling.All:
writer.WriteStartObject();
writer.WritePropertyName("$type", false);
switch (serializer.TypeNameAssemblyFormat)
{
case FormatterAssemblyStyle.Full:
writer.WriteValue(value.GetType().AssemblyQualifiedName);
break;
default:
writer.WriteValue(value.GetType().FullName);
break;
}
writer.WritePropertyName("$value", false);
writer.WriteValue(value);
writer.WriteEndObject();
break;
default:
writer.WriteValue(value);
break;
}
}
}
以下是如何使用它:
JsonSerializerSettings settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All,
};
settings.Converters.Insert(0, new PrimitiveJsonConverter());
return JsonConvert.SerializeObject(myDotNetObject, settings);
我目前正在使用此解决方案序列化可包含基元的IDictionary<string, object>
实例。
答案 1 :(得分:2)
将它们混合在一起并进行测试。显然,这需要单元测试,更像是一个概念验证。如果你想要一个肮脏的解决方案让你去,这应该开始。
https://github.com/xstos/Newtonsoft.Json/commit/8d3507cbba78f7096a82e42973e56d69c9541c42