2012-12-10 34 views
8

使用JSON.Net序列化/反序列化结构时,内置结构类型(如System.Drawing.Size)序列化为字符串,而自定义结构类型序列化为JSON对象。JSON.Net结构序列化差异

例如:

using System; 
using System.Drawing; 
using Newtonsoft.Json; 

namespace TestJsonNet 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine(JsonConvert.SerializeObject(new Size(50, 50))); 
      Console.WriteLine(JsonConvert.SerializeObject(new Size2(50, 50))); 
     } 
    } 

    struct Size2 
    { 
     public int Width { get; set; } 
     public int Height { get; set; } 
     public Size2(int w, int h) : this() 
     { 
      Width = w; Height = h; 
     } 
    } 
} 

输出如下:

"50, 50" 
{"Width":50,"Height":50} 

我能理解后面序列化结构为一个字符串的思维,因为内存布局始终是相同的;然而,为什么序列化自定义结构时出现差异?

另外,我会(为了内部遗留的原因),喜欢让JSON.Net序列化结构像后一种情况(即作为JSON,而不是字符串)。如果可能的话,那怎么能实现呢?

+1

我没有找到这篇文章[JSON.NET系列化麻烦(http://stackoverflow.com/questions/9750836/json-net-serialization-trouble) ,但是我仍然想要一举关闭所有结构类型的这种行为。 –

回答

2

使用反射可以解决这个问题。 我参与了你自己建议的解决方案,并使用反射来获取属性名称和值。

class StructConverter : JsonConverter 
{ 
    public override void WriteJson(
     JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var myObject = (object)value; 
     var jObject = new JObject(); 

     Type myType = myObject.GetType(); 
     IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties()); 

     foreach (PropertyInfo prop in props) 
     { 

      jObject.Add(prop.Name, prop.GetValue(myObject, null).ToString()); 
     } 
     serializer.Serialize(
      writer, jObject); 
    } 

....

public override bool CanConvert(Type objectType) 
    { 
     return objectType.IsValueType; 
    } 
} 
+0

我的问题真正的答案是:你不能。没有办法配置JSON.NET,因此它使用自己的转换器而不是TypeConverter。但是,我会给你支票(和巫师徽章?),因为它可能是最通用的。 –

+0

谢谢戴夫。我想知道是否有用于.net的JSON序列化程序可以实现这一点。 –

+0

是的,有。看看ServiceStack.Text。如果你为结构提供了两个Parse和ToString函数,那么就需要这些函数来反序列化和序列化。我觉得它非常有用。 – jruizaranguren