Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I optionally turn off the JsonIgnore attribute at runtime?

Tags:

c#

.net

json.net

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 reduce the size and added JsonIgnore and custom formatting for some datatypes.

The result is a reduction from 24MB to 1MB, which is great; however, I'd like the option to produce either the full version or the reduced property version at runtime.

Is there anyway I can get the serializer to optionally use the attributes?

like image 626
Dan Craigen Avatar asked May 22 '16 07:05

Dan Craigen


People also ask

How to ignore JSON attribute?

To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.

Which of the following attribute should be used to indicate the property must not be serialized while using .JSON serializer?

Apply a [JsonIgnore] attribute to the property that you do not want to be serialized.

What is JSON serialization?

Serialization is the process of converting . NET objects such as strings into a JSON format and deserialization is the process of converting JSON data into . NET objects.


1 Answers

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<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)     {         IList<JsonProperty> 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

like image 69
Brian Rogers Avatar answered Oct 05 '22 04:10

Brian Rogers