当我们使用JSON.Net序列化可序列化对象时,JSON字符串与DatacontractJSON序列化程序不同
本文关键字:序列化 JSON 字符串 DatacontractJSON 程序 对象 我们 Net | 更新日期: 2023-09-27 18:28:16
我有一个类似的类
[Serializable]
public class sample
{
private int m_width;
private int m_height;
public int Width
{
get
{
return this.m_width;
}
set
{
this.m_width = value;
}
}
public int Height
{
get
{
return this.m_height;
}
set
{
this.m_height = value;
}
}
}
如果我使用DataContractJsonSerializer
来序列化这个类的对象,我会得到如下的json
字符串:
{"m_height":1345,"m_width":1234}
如果我使用Newtonsoft.Json.dll来序列化它,我得到的输出如下:
{"Width":1234,"Height":1345}
如果类标记为可序列化,为什么DataContractSerializer使用支持字段进行序列化?
有什么方法可以使用Newtonsoft.Json.dll
实现同样的效果吗
我们有一些对象被标记为[Serializable]
,因此它们可以使用传统方法串行化,但我们需要在JSON中干净地串行化,以便与Web API一起使用。将IgnoreSerializableAttribute
设置为true
将阻止Newtonsoft.Json表现得像Microsoft的串行化器,相反,它只会串行化公共属性。
TLDR:将其添加到WebApiConfig.cs:
((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;
除非您总是从WCF到WCF进行通信,否则最好的选择可能是使用Newtonsoft序列化程序。不幸的是,MS序列化程序似乎遵循了一些特定于Microsoft的标准,这些标准与许多web应用程序所期望的标准不匹配。
Newtonsoft的序列化程序似乎更标准,甚至MS也将其用于WebAPI,并在Web API http客户端中使用(nuget将为您删除它)。
您会发现另一个不同之处——尝试序列化DateTime类型。您会发现DataContract序列化程序以不同的格式序列化值,该格式与其他JSON不兼容(您会注意到其中有一些斜杠)。我的理解是,一些AJAX WebForm控件使用了这种替代格式,但它是特定于Microsoft Webforms的。
以下是有关日期的更多信息:http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx
您可能会看到另一件事:
DataContractJsonSerializer和Newtonsoft之间的差异仍然存在,但至于为什么会出现奇怪的序列化行为,则是混合了序列化标准。
[Serializable]属性属于较旧的.Net序列化。DataContractSerialization是向后兼容的,但行为可能不同。
如果您想以datacontract的方式执行此操作,请使用改为[DataContract]属性,并用[DataMember]属性标记要序列化的每个公共成员。(或者删除所有序列化属性,它应该默认为所有公共属性)
这应该可以解释所看到的差异,但我仍然建议您更喜欢Newtonsoft序列化程序。
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40)
IgnoreSerializableAttribute = true;
#endif
我正在使用DotNet4.0 dll,因此此属性设置为true,并且它正在忽略Serializable属性。如果我将其设为false,它将提供与DataContractSerializer 相同的输出
DataContract序列化程序要求用[DataContract]
属性显式标记类,然后用[DataMember]
属性标记每个需要序列化的属性。
如果你这样做,你会发现相同的json字符串会像使用其他类一样输出。您遇到的问题是由于两个序列化程序处理默认序列化的方式不同(没有指定其他信息):
DataContract序列化所有私有字段,除非另有指定
NewtonSoft序列化所有公共属性,除非另有指定
关于如何使Newtonsoft序列化私有字段,我没有其他想法,只能制作一个具有m_Width和m_Height属性的包装类,在setter和geter上将值放入实际对象的正确目标属性中