简体   繁体   English

Json.Net属性忽略所有属性

[英]Json.Net attribute to ignore all properties

Is there an attribute to tell json.net to ignore all properties of a class but include all fields (regardless of access modifiers) ? 是否有一个属性告诉json.net忽略类的所有属性但包含所有字段(不管访问修饰符)?

If not is there a way to create one ? 如果没有,有没有办法创建一个?

Basically I want one attribute decorating the class that will have the equivalent effect to putting [JsonIgnore] infront of each property. 基本上我想要一个属性来装饰这个类,它具有与每个属性[JsonIgnore]放置[JsonIgnore]相同的效果。

If you mark your class with [JsonObject(MemberSerialization.Fields)] , that will get you most of the way there. 如果使用[JsonObject(MemberSerialization.Fields)]标记您的类,那么这将使您获得大部分内容。 This attribute tells Json.Net that you want it to serialize all fields in a class, regardless of access modifiers, but not properties. 此属性告诉Json.Net您希望它序列化类中的所有字段,而不管访问修饰符,而不是属性。

However, if you have any auto properties in your class (ie those declared with { get; set; } ) then this attribute will cause the compiler-generated backing fields to be serialized as well, which you may not want. 但是,如果您的类中有任何自动属性(即使用{ get; set; }声明的那些属性),则此属性将导致编译器生成的支持字段也被序列化,您可能不需要。 To suppress those, you will need to use a custom IContractResolver . 要禁止这些,您需要使用自定义IContractResolver You can create one by inheriting from the DefaultContractResolver and overriding the CreateProperty method. 您可以通过继承DefaultContractResolver并重写CreateProperty方法来创建一个。 In that method, check whether the class has the [JsonObject(MemberSerialization.Fields)] attribute applied, and if so, check whether the member is a compiler-generated field. 在该方法中,检查该类是否应用了[JsonObject(MemberSerialization.Fields)]属性,如果是,则检查该成员是否是编译器生成的字段。 If it is, then set it to be ignored. 如果是,则将其设置为忽略。

class CustomResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty prop = base.CreateProperty(member, memberSerialization);
        JsonObjectAttribute attr = prop.DeclaringType.GetCustomAttribute<JsonObjectAttribute>();
        if (attr != null && attr.MemberSerialization == MemberSerialization.Fields && 
            member.GetCustomAttribute<CompilerGeneratedAttribute>() != null)
        {
            prop.Ignored = true;
        }
        return prop;
    }
}

To use the resolver, you need to pass it to the SerializeObject method via the JsonSerializerSettings : 要使用解析器,需要通过JsonSerializerSettings将其传递给SerializeObject方法:

var settings = new JsonSerializerSettings
{
    ContractResolver = new CustomResolver(),
    Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(yourObject, settings);

Here is a proof of concept: https://dotnetfiddle.net/aNXWbn 这是一个概念证明: https//dotnetfiddle.net/aNXWbn

You can add [JsonObject(MemberSerialization.OptIn)] attribute to your class, then everything will be ignored unless you explicitly Opt-In by using a [JsonProperty] attribute on the members. 您可以将[JsonObject(MemberSerialization.OptIn)]属性添加到您的类中,然后一切都将被忽略,除非您通过在成员上使用[JsonProperty]属性显式选择。

[JsonObject(MemberSerialization.OptIn)]
public class Address
{
    [JsonProperty]
    private string _field1 = "bob";

    public string Line1 { get; set; }

    public string Line2 { get; set; }

    public string Line3 { get; set; }
}

For example 例如

using System;
using AutoFixture;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        var fixture = new Fixture();
        var address = fixture.Create<Address>(); // Create an address filled with junk

        var json = JsonConvert.SerializeObject(address);

        Console.WriteLine(json);
    }
}

Will output: 将输出:

{"_field1":"bob"}

You could create a custom IContractResolver and decide to serialize depending on a custom attribute you created: 您可以创建自定义IContractResolver并根据您创建的自定义属性决定序列化:

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

        //Todo: Check your custom attribute. You have MemberInfo here to navigate to your class and GetCustomAttributes<>
        //e.g: property.ShouldSerialize = member.DeclaringType.GetCustomAttribute<JsonIgnoreAllProperties>() == null;
        property.ShouldSerialize = false; 
        return property;
    }
}

Then you need to register it as default, which depends on your environment. 然后,您需要将其注册为默认值,具体取决于您的环境。 Or you are using it directly, then you even do not need an attribute: 或者您直接使用它,那么您甚至不需要属性:

string json =
    JsonConvert.SerializeObject(
        product,
        Formatting.Indented,
        new JsonSerializerSettings
        {
            ContractResolver = new IgnorePropertyResolver()
        }
    );

An attribute is created for example by: 例如,通过以下方式创建属性

public class JsonIgnoreAllPropertiesAttribute : Attribute
{
}

And Used: 并使用:

[JsonIgnoreAllProperties]
public class ClassToSerialize
{
     public int Ignored { get;set; }
     public int Serialized;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM