2

我有一个包含许多数据合同的系统,其中成员装饰有:

[DataMember(EmitDefaultValue = false)]  

我有一个案例,当序列化为 JSON 时,我需要在 null 时包含成员。无论我选择什么序列化程序设置,我都无法让它工作。

   [TestMethod]
    public void SerializationTest()
    {

        var contract = Activator.CreateInstance(typeof(TestContract));

        var formatter = new JsonMediaTypeFormatter
        {
            SerializerSettings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Include,
                DefaultValueHandling = DefaultValueHandling.Ignore,
                TypeNameHandling = TypeNameHandling.All,
                ContractResolver = new DataContractResolver(),
                Binder = new DataContractBinder()
            }
        };

        var result = JsonConvert.SerializeObject(contract, formatter.SerializerSettings);
    }

我什至创建了一个自定义数据协定解析器,它为每个属性提供额外的覆盖。

        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {                        
        var property = base.CreateProperty(member, MemberSerialization.Fields);                        
        property.NullValueHandling = NullValueHandling.Include;            
        property.DefaultValueHandling = DefaultValueHandling.Ignore;
        property.ShouldSerialize = o => true;
        return property;
    }

我已经尝试了空值处理和默认值处理的所有变体来忽略发出默认值 = false。根据 json net docs,这些设置应该为我的对象提供 null 属性。在我去调试 json 网络源之前,我还缺少什么吗?

4

1 回答 1

7

您需要设置property.DefaultValueHandling = DefaultValueHandling.Include而不是DefaultValueHandling.Ignore在合同解析器中:

public class DataContractResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        property.NullValueHandling = NullValueHandling.Include;
        property.DefaultValueHandling = DefaultValueHandling.Include;
        property.ShouldSerialize = o => true;
        return property;
    }
}

Json.NET在序列化成员之前DefaultValueHandling和之前都会进行检查,并且必须通过这两项检查才能序列化成员。而且,正如您所注意到的,如果在合同的属性上明确设置了任何一个,那么这将覆盖. 这解释了为什么需要自定义合同解析器。NullValueHandlingJsonSerializerSettings

您可能希望缓存合约解析器以获得最佳性能。

于 2016-08-15T19:07:39.113 回答