Json.Net属性忽略所有属性

时间:2018-07-02 22:23:32

标签: c# json.net

是否有一个属性告诉json.net忽略类的所有属性,但包括所有字段(与访问修饰符无关)?

如果没有,可以创建一个吗?

基本上,我想要一个装饰类的属性,该属性具有与将[JsonIgnore]放在每个属性前面的效果相同。

3 个答案:

答案 0 :(得分:1)

您可以将[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; }
}

例如

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);
    }
}

将输出:

{"_field1":"bob"}

答案 1 :(得分:1)

您可以创建自定义IContractResolver并决定根据创建的custom attribute进行序列化:

 >>> b = a[:],[0,2]

然后,您需要将其注册为默认值,具体取决于您的环境。或直接使用它,甚至不需要属性:

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;
    }
}

attribute is created例如:

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

并使用:

public class JsonIgnoreAllPropertiesAttribute : Attribute
{
}

答案 2 :(得分:1)

如果您用[JsonObject(MemberSerialization.Fields)]标记班级,那将为您提供大部分帮助。该属性告诉Json.Net,您希望它序列化一个类中的所有字段,而与访问修饰符无关,而与属性无关。

但是,如果您的类中有任何自动属性(即用{ get; set; }声明的那些自动属性),则此属性将导致编译器生成的后备字段也被序列化,而这可能是您不希望的。要禁止这些行为,您将需要使用自定义IContractResolver。您可以通过从DefaultContractResolver继承并覆盖CreateProperty方法来创建一个。在该方法中,检查该类是否应用了[JsonObject(MemberSerialization.Fields)]属性,如果是,则检查该成员是否是编译器生成的字段。如果是这样,则将其设置为忽略。

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;
    }
}

要使用解析器,您需要通过SerializeObject将其传递到JsonSerializerSettings方法:

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

以下是概念证明:https://dotnetfiddle.net/aNXWbn