Can I optionally turn off the JsonIgnore attribute at runtime?

后端 未结 3 878
一生所求
一生所求 2020-11-29 05:41

I am creating a JSON file with Newtonsoft.Json from a set of classes. The file created is very large, so I have created JsonProperty\'s for the properties to re

3条回答
  •  情歌与酒
    2020-11-29 06:27

    Yes, this can be done using a custom ContractResolver.

    You didn't show any code, so I'll just make up an example. Let's say I have a class Foo as shown below. I want the Id and Name properties in the serialization output, but I'm definitely not interested in the AlternateName and Color. I've marked those with [JsonIgnore]. I want the description to appear, but sometimes this can get really long, so I've used a custom JsonConverter to limit its length. I also want to use a shorter property name for the description, so I've marked it with [JsonProperty("Desc")].

    class Foo
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [JsonIgnore]
        public string AlternateName { get; set; }
        [JsonProperty("Desc")]
        [JsonConverter(typeof(StringTruncatingConverter))]
        public string Description { get; set; }
        [JsonIgnore]
        public string Color { get; set; }
    }
    

    When I serialize an instance of the above...

    Foo foo = new Foo
    {
        Id = 1,
        Name = "Thing 1",
        AlternateName = "The First Thing",
        Description = "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.",
        Color = "Yellow"
    };
    
    string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
    

    ...I get this output:

    {
      "Id": 1,
      "Name": "Thing 1",
      "Desc": "This is some lengthy text describing Thing 1 "
    }
    

    Now, let's say that I sometimes want to get the full JSON output, ignoring my customizations. I can use a custom ContractResolver to programmatically "unapply" the attributes from the class. Here's the code for the resolver:

    class IgnoreJsonAttributesResolver : DefaultContractResolver
    {
        protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            IList props = base.CreateProperties(type, memberSerialization);
            foreach (var prop in props)
            {
                prop.Ignored = false;   // Ignore [JsonIgnore]
                prop.Converter = null;  // Ignore [JsonConverter]
                prop.PropertyName = prop.UnderlyingName;  // restore original property name
            }
            return props;
        }
    }
    

    To use the resolver, I add it to the JsonSerializerSettings and pass the settings to the serializer like this:

    JsonSerializerSettings settings = new JsonSerializerSettings();
    settings.ContractResolver = new IgnoreJsonAttributesResolver();
    settings.Formatting = Formatting.Indented;
    
    string json = JsonConvert.SerializeObject(foo, settings);
    

    The output now includes the ignored properties, and the description is no longer truncated:

    {
      "Id": 1,
      "Name": "Thing 1",
      "AlternateName": "The First Thing",
      "Description": "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.",
      "Color": "Yellow"
    }
    

    Full demo here: https://dotnetfiddle.net/WZpeWt

提交回复
热议问题