C# 将JSON.NET配置为忽略DataContract/DataMember属性

C# 将JSON.NET配置为忽略DataContract/DataMember属性,c#,json,json.net,datacontract,datamember,C#,Json,Json.net,Datacontract,Datamember,我们在一个MVC3项目中遇到了一种情况,该项目同时使用了Microsoft JSON序列化程序和JSON.NET 每个人都知道DateTime在微软的序列化程序中基本上是不完整的,所以我们切换到JSON.NET来避免这个问题。这非常有效,只是我们尝试序列化的一些类是具有DataContract/DataMember属性的poco。它们在多个位置引用的部件中定义。此外,为了提高效率,它们还有一些未标记为DataMembers的其他显示属性。例如,客户 [DataContract] public c

我们在一个MVC3项目中遇到了一种情况,该项目同时使用了Microsoft JSON序列化程序和JSON.NET

每个人都知道DateTime在微软的序列化程序中基本上是不完整的,所以我们切换到JSON.NET来避免这个问题。这非常有效,只是我们尝试序列化的一些类是具有DataContract/DataMember属性的poco。它们在多个位置引用的部件中定义。此外,为了提高效率,它们还有一些未标记为DataMembers的其他显示属性。例如,客户

[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属性,但是DateTimes被破坏了。我需要JSON.NET忽略这个类具有DataContract/DataMember属性的事实,只需执行标准公共字段序列化,就像它们不存在一样。

您尝试过这个吗

你试过这个吗


我遇到了一个几乎与您所遇到的问题有关的问题,并通过查看Json.NET的代码找到了解决方案。所以这可能不是最好的解决方案,但对我来说很有效

为此,您需要实现自己的
IContractResolver
。这是一个过度简化的实现,它包含所有参数并忽略所有属性(不仅仅是
DataContract
,还包括其他内置的Json.NET规则,因此您设置的任何原本会影响成员选择的选项现在都被此代码覆盖):


我遇到了一个几乎与您所遇到的问题有关的问题,并通过查看Json.NET的代码找到了一个解决方案。所以这可能不是最好的解决方案,但对我来说很有效

为此,您需要实现自己的
IContractResolver
。这是一个过度简化的实现,它包含所有参数并忽略所有属性(不仅仅是
DataContract
,还包括其他内置的Json.NET规则,因此您设置的任何原本会影响成员选择的选项现在都被此代码覆盖):


正如Amry所说,您可以使用自己的IContractResolver

不幸的是,安利提供的解决方案不适用于我,以下是我设法找到的解决方案:

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;
    }
}
有几行评论说,这些不是使我的解决方案工作所必需的,但你永远不知道

这与安利的解决方案具有相同的用途:

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

希望这有帮助

正如Amry所说,您可以使用自己的IContractResolver

不幸的是,安利提供的解决方案不适用于我,以下是我设法找到的解决方案:

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;
    }
}
有几行评论说,这些不是使我的解决方案工作所必需的,但你永远不知道

这与安利的解决方案具有相同的用途:

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

希望这有帮助

根据Json.NET文档
[DataMember]
如果属性也用Json.NET特定属性(例如
[JsonProperty]
)注释,则属性将被忽略。有关详细信息,请参阅:

Json.NET属性优先于标准的.NET序列化属性,例如,如果属性上同时存在JsonPropertyAttribute和DataMemberAttribute,并且都自定义了名称,则将使用JsonPropertyAttribute中的名称


本文档仅涉及name属性,但根据我的经验,
[JsonProperty]
属性也完全隐藏了由
[DataMember]
属性完成的设置。因此,如果您的情况可行,也可以将Json.NET属性添加到应忽略[DataMember]注释的属性中。

根据Json.NET文档,如果属性也使用Json.NET特定属性进行注释(例如
[JsonProperty]
),则忽略属性。详情请参阅:

Json.NET属性优先于标准的.NET序列化属性,例如,如果属性上同时存在JsonPropertyAttribute和DataMemberAttribute,并且都自定义了名称,则将使用JsonPropertyAttribute中的名称


本文档仅涉及name属性,但根据我的经验,
[JsonProperty]
属性也完全隐藏了由
[DataMember]
属性完成的设置。因此,如果您的情况可行,也可以将Json.NET属性添加到属性中,而[DataMember]注释应该被忽略。

只需使用Json.NET的OptOut属性即可。它将优先于DataContract

[DataContract]
[JsonObject(MemberSerialization.OptOut)]

只需使用Json.Net的OptOut属性。它将优先于DataContract

[DataContract]
[JsonObject(MemberSerialization.OptOut)]

如果要忽略所有类型的
DataContractAttribute
,而无需添加其他属性,则a是正确的解决方案。但是,从Json.NET 9.0.1开始,它就不再工作了。但它还有一个额外的副作用,那就是序列化所有公共属性,包括标记为的属性。如果您需要一个只忽略存在
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;
        }
    }
}
公共类IgnoreDataContractResolver:DefaultContractResolver
{
静态MemberSerialization RemoveDataContractAttributeMemberSerialization(类型类型,MemberSerialization MemberSerialization)
{
if(memberSerialization==memberSerialization.OptIn)
{
类型=可空。GetUnderlineType(类型)??类型;
//Json.NET解释数据