使用JSON.NET在C#中进行不正确的序列化

本文关键字:不正确 序列化 JSON NET 使用 | 更新日期: 2023-09-27 18:22:11

我正试图获取一个结构类似的对象

public class Item
{
   public Guid SourceTypeID {get;set;}
   public Guid BrokerID {get;set;}
   public double Latitude {get;set;}
   public double Longitude {get;set;}
   public DateTime TimeStamp {get;set;}
   public object Payload {get;set;}
}

并使用以下调用将其与JSON.NET串行化:

Item expected = new Item()
{
   SourceTypeID = Guid.NewGuid(),
   BrokerID = Guid.NewGuid(),
   Latitude = 33.657145,
   Longitude = -117.766684,
   TimeStamp = DateTime.Now,
   Payload = new byte[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
};
string jsonString = JsonConvert.SerializeObject(expected);

Item对象的有效负载成员可能包含C#基元列表中的任何一个基元(加上一些其他基元,如Guid),或这些类型的数组(如本例中的字节数组),或由先前列出的任何"基元"组成的"平面"对象(动态创建)。

当我执行SerializeObject()调用时,生成的字符串包含:

{"Payload":"AAECAwQFBgcICQ==","SourceTypeID":"d8220a4b-75b1-4b7a-8112-b7bdae956a45",
 "BrokerID":"951663c4-924e-4c86-a57a-7ed737501dbd",
 "TimeStamp":"'/Date(1328202421559-0600)'/",
 "Latitude":33.657145,"Longitude":-117.766684}

然而,当我进行反序列化调用时,生成的项是部分不正确的

Item actual = JsonConvert.DeserializeObject<Item>(jsonString);
actual.SourceTypeID : {00000000-0000-0000-0000-000000000000}
actual.BrokerID : {951663c4-924e-4c86-a57a-7ed737501dbd}
actual.Latitude : 33.657145;
actual.Longitude : -117.766684;
actual.TimeStamp : {2/2/2012 11:07:01 AM}
actual.Payload : null

SourceTypeID成员(Guid)和Payload成员(持有字节[]的对象)都不正确。序列化的字符串似乎包含guid的正确标识,但不包含字节数组的正确标识。

我看到SerializeObject的另一个签名是

SerializeObject(object value, params JsonConverter[] converters);

这是向反序列化引擎通知它显然处理错误的类型的正确方式吗?由于我在对象的核心使用一组有限的"基元",如果我能为每种类型创建一组转换器,这能解决我的问题吗?

如果可能的话,我想避免重新发明轮子,因为这似乎是一个已经得到妥善处理的问题,如果有这样的东西,我想利用它。

使用JSON.NET在C#中进行不正确的序列化

Payload将被反序列化为字符串,除非您在其上放置启用了TypeNameHandling的[JsonProperty]属性,否则反序列化器将不知道将其反序列化为什么。

我无法使用上的最新源代码复制您遇到的一些属性为null的问题http://json.codeplex.com/SourceControl/list/changesets

这似乎是JSON.NET中的一个实际错误。

这不是一个主意,但一个变通方法可能是进行两阶段序列化。第一个对象,实际被序列化到JSON或从JSON序列化的对象,将仅由string类型的字段/属性组成。第二个对象(服务器端代码将使用的对象)将是一个手动转换为强类型的对象。

不理想,但可能。另外,您可以考虑使用DataContractJsonSerializer,它在处理字节数组和guidIME方面做得很好。日期仍然很糟糕,但这主要是Javascript的错。