4

我有一堂课,如下所示

[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

4

5 回答 5

2

我们有一些对象被标记为[Serializable]可以使用传统方法进行序列化,但我们需要在 JSON 中干净地序列化这些对象才能与 Web API 一起使用。设置IgnoreSerializableAttributetrue将阻止 Newtonsoft.Json 的行为类似于 Microsoft 的序列化程序,而只会序列化公共属性。

TLDR:将此添加到 WebApiConfig.cs:

((Newtonsoft.Json.Serialization.DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;
于 2016-04-28T08:15:15.610 回答
1

除非您总是从 WCF 到 WCF 进行通信,否则最好的选择可能是使用 Newtonsoft 序列化程序。不幸的是,MS 序列化程序似乎遵循一些与许多 Web 应用程序期望的标准不匹配的 Microsoft 特定标准。

Newtonsoft 的序列化器似乎更标准,甚至 MS 都将它用于 WebAPI,并在 Web API http 客户端中(nuget 会为您拉下它)。

这是您会发现的另一个区别——尝试序列化 DateTime 类型。您会发现 DataContract 序列化程序以与其他 JSON 不兼容的不同格式序列化值(您会注意到其中有一些斜线)。我的理解是,某些 AJAX WebForm 控件使用了这种替代格式,但它特定于 Microsoft Webforms。

以下是有关日期的更多信息:http ://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx

于 2013-08-19T13:41:50.440 回答
1

这是您可能会看到的另一件事:

DataContractJsonSerializer 和 Newtonsoft 之间的区别仍然存在,但至于为什么你会得到奇怪的序列化行为——你正在混合你的序列化标准。

[Serializable] 属性属于较旧的 .Net 序列化。DataContractSerialization 向后兼容,但行为可能不同。

如果您想以数据合同的方式执行此操作,请使用 [DataContract] 属性标记您的类,并使用 [DataMember] 属性标记您想要序列化的每个公共成员。(或删除所有序列化属性,它应该默认为所有公共属性)

这应该可以解释所看到的差异,但我仍然建议您更喜欢 Newtonsoft 序列化程序。

于 2013-08-19T14:31:33.217 回答
1

Newtonsoft.Json.dll 中的 DefaultContractResolver 类我发现了一些将 IgnoreSerializableAttribute 属性设置为 true 的代码。

#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40)
    IgnoreSerializableAttribute = true;
#endif

我使用的是 DotNet4.0 dll,所以这个属性设置为 true,它忽略了 Serializable 属性。如果我把它设为假,它会给出与 DataContractSerializer 相同的输出

于 2013-08-20T07:15:41.877 回答
0

DataContract 序列化程序要求您使用属性显式标记类,[DataContract]然后使用属性标记要序列化的每个所需[DataMember]属性。

如果你这样做,你会发现与使用其他类相同的 json 字符串。您遇到的问题是由于 2 个序列化程序处理默认序列化的方式不同(未指定其他信息):

  1. 除非另有说明,否则DataContract 会序列化所有私有字段

  2. NewtonSoft 序列化所有公共属性,除非另有说明

关于如何让 Newtonsoft 序列化私有字段,除了使用 m_Width 和 m_Height 属性创建一个包装器类之外,我没有别的想法,在 setter 和 geters 上将值放入实际对象的正确目标属性中

于 2013-08-19T15:48:58.637 回答