我有一个课程,如下面的
[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
答案 0 :(得分:2)
我们有一些标记为[Serializable]
的对象,因此可以使用传统方法对它们进行序列化,但我们需要在JSON中对其进行干净序列化以便与Web API一起使用。将IgnoreSerializableAttribute
设置为true
会阻止Newtonsoft.Json表现得像微软的串行器,而只是序列化公共属性。
TLDR:将其添加到WebApiConfig.cs:
((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;
答案 1 :(得分:1)
除非您始终从WCF与WCF进行通信,否则最好的选择可能是使用Newtonsoft序列化程序。不幸的是,MS序列化程序似乎遵循一些微软特定的标准,这些标准与许多网络应用所期望的标准不符。
Newtonsoft的序列化程序似乎更标准,甚至MS也将它用于WebAPI,而在Web API http客户端(nuget会为你拉下它)。
这是您将找到的另一个区别 - 尝试序列化DateTime类型。您会发现DataContract序列化器以不同的格式序列化该值,该格式与其他JSON不兼容(您会注意到其中的一些斜杠)。我的理解是,某些AJAX WebForm控件使用了这种替代格式,但它特定于Microsoft Webforms。
以下是关于日期的更多信息:http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx
答案 2 :(得分:1)
这是你可能会看到的另一件事:
DataContractJsonSerializer和Newtonsoft之间的差异仍然存在,但是为什么你会得到奇怪的序列化行为 - 你正在混合你的序列化标准。
[Serializable]属性适用于较旧的.Net序列化。 DataContractSerialization是向后兼容的,但行为可能不同。
如果你想以datacontract的方式做这件事,请用。标记你的课程 改为[DataContract]属性,并使用[DataMember]属性标记要序列化的每个公共成员。 (或删除所有序列化属性,它应默认为所有公共属性)
这应该解释看到的差异,但我仍然建议您更喜欢Newtonsoft序列化器。
答案 3 :(得分:1)
Newtonsoft.Json.dll中的DefaultContractResolver类我发现了一些将IgnoreSerializableAttribute属性设置为true的代码。
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40)
IgnoreSerializableAttribute = true;
#endif
我正在使用DotNet4.0 dll,因此该属性设置为true,它忽略了Serializable属性。如果我将其设为false,则它提供与DataContractSerializer相同的输出
答案 4 :(得分:0)
DataContract序列化程序要求您使用[DataContract]
属性显式标记该类,然后使用[DataMember]
属性标记要序列化的每个所需属性。
如果你这样做,你会发现相同的json字符串将使用另一个类。 您遇到的问题是由于2个序列化程序如何处理默认序列化(未指定其他信息)的差异:
除非另有说明,否则DataContract会序列化所有私有字段
NewtonSoft序列化所有公共属性,除非另有说明
关于如何使Newtonsoft序列化私有字段除了使用m_Width和m_Height属性创建包装类之外,我不知道如何在setter和geters上将值放在实际对象的正确目标属性中