配置JSON.NET忽略DataContract /数据成员属性配置JSON.NET忽略DataCo

2019-06-17 10:04发布

我们正在运行到上同时与微软JSON序列化和JSON.NET一个MVC3项目的情况。

大家都知道的DateTime的是微软的串行基本上打破,所以我们切换到JSON.NET以避免此问题。 除了一些我们试图序列化类都是波苏斯与DataContract /的DataMember属性,这些属性的伟大工程。 他们在在多个地方引用的程序规定。 此外,它们具有未标记为数据成员为效率一些其它显示属性。 例如,一个客户

[DataContract]
public class Customer
{
   [DataMember]
   public string FirstName { get; set;}
   [DataMember]
   public string LastName { get; set;}
   public string FullName 
   {
       get
       {  return FirstName + " " + LastName; }
   }

}

当该客户经过WCF客户端可以引用组装和使用全名就好了,但与JSON.NET连载它看到全名不是一个[DataMember]并不会对其进行序列化。 有没有传递到JSON.NET告诉它忽略一个类事实的选项[DataContract]加属性?

注意:使用.NET中的JavaScriptSerializer工作正常FullName属性,但DateTime是否被破坏。 我需要JSON.NET忽略这一类有DataContract /的DataMember属性的事实,只是做普通的公开领域系列化就像它将如果他们不存在。

Answer 1:

只需使用Json.Net的选择禁用属性。 这将优先于DataContract。

[DataContract]
[JsonObject(MemberSerialization.OptOut)]


Answer 2:

正如Amry说,你可以使用你自己的IContractResolver。

不幸的是由Amry提供的解决方案,我没有工作,下面是我设法获得工作的解决方案:

public class AllPropertiesResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty property = base.CreateProperty(member, memberSerialization);

        //property.HasMemberAttribute = true;
        property.Ignored = false;

        //property.ShouldSerialize = instance =>
        //{
        //    return true;
        //};

        return property;
    }
}

有评论说几行,这些wern't要求使我的解决方案的工作,但你永远不知道!

这有相同的使用作为Amry的解决方案:

var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings {
    ContractResolver = new AllPropertiesResolver()
});

希望这可以帮助!



Answer 3:

我有几乎涉及您遇到什么问题,并设法找到通过Json.NET的代码去解决。 因此,它可能不是最好的解决办法,但它为我工作。

要做到这一点,你需要实现自己的IContractResolver 。 这方面的一个过于简单的实现,包括所有的参数,并忽略所有属性(不只是DataContract ,但其他内置Json.NET的规则一样,所以无论你选择设置本来应该影响到会员选择现在正由该代码overidden ):

class AllPropertiesResolver : DefaultContractResolver
{
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        return objectType.GetProperties()
            .Where(p => p.GetIndexParameters().Length == 0)
            .Cast<MemberInfo>()
            .ToList();
    }
}

这里谈到的代码使用示例:

var json = JsonConvert.SerializeObject(result, new JsonSerializerSettings {
    ContractResolver = new AllPropertiesResolver()
});


Answer 4:

如果你想忽略的存在DataContractAttribute所有类型,而不必增加额外的属性,那么定制合同解析器是正确的解决方案。 然而,随着Json.NET的9.0.1 Amry的解析器不再起作用。 Doolali的解析工作,但它具有序列化的所有公共属性,包括那些标有额外的副作用[JsonIgnore] 如果你需要一个合同解析器, 只有忽略的存在DataContractAttribute但其他行为类似于默认的合同解析器中,可以使用下列:

public class IgnoreDataContractContractResolver : DefaultContractResolver
{
    static MemberSerialization RemoveDataContractAttributeMemberSerialization(Type type, MemberSerialization memberSerialization)
    {
        if (memberSerialization == MemberSerialization.OptIn)
        {
            type = Nullable.GetUnderlyingType(type) ?? type;

            // Json.NET interprets DataContractAttribute as inherited despite the fact it is marked with Inherited = false
            // https://json.codeplex.com/discussions/357850
            // https://stackoverflow.com/questions/8555089/datacontract-and-inheritance
            // https://github.com/JamesNK/Newtonsoft.Json/issues/603
            // Thus we need to manually climb the type hierarchy to see if one is present.

            var dataContractAttribute = type.BaseTypesAndSelf().Select(t => t.GetCustomAttribute<DataContractAttribute>()).FirstOrDefault(a => a != null);
            var jsonObjectAttribute = type.GetCustomAttribute<JsonObjectAttribute>();

            if (dataContractAttribute != null && jsonObjectAttribute == null)
                memberSerialization = MemberSerialization.OptOut;
        }
        return memberSerialization;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, RemoveDataContractAttributeMemberSerialization(type, memberSerialization));
        return properties;
    }

    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        var contract = base.CreateObjectContract(objectType);
        contract.MemberSerialization = RemoveDataContractAttributeMemberSerialization(objectType, contract.MemberSerialization);
        return contract;
    }
}

public static class TypeExtensions
{
    public static IEnumerable<Type> BaseTypesAndSelf(this Type type)
    {
        while (type != null)
        {
            yield return type;
            type = type.BaseType;
        }
    }
}

你可能想缓存以获得最佳性能的合同解析器 。



Answer 5:

根据到Json.NET文档[DataMember]如果属性也与Json.NET特定属性(如注释被忽略的属性[JsonProperty]参见的序列化属性的文档的详细信息:

Json.NET属性接管标准.NET序列化的属性,例如,如果遵和JsonPropertyAttribute都DataMemberAttribute上存在的属性和两个自定义名称,将使用从JsonPropertyAttribute名称。

文档只覆盖了name属性,但我的经验[JsonProperty]属性也完全阴影在完成设置[DataMember]属性。 所以,如果这是你的情况下是可行的,还加Json.NET属性为其[数据成员]注释应该被忽略的属性。



Answer 6:

您是否尝试过这个?

IgnoreDataMemberAttribute



文章来源: Configure JSON.NET to ignore DataContract/DataMember attributes