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?
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.
Apply a [JsonIgnore] attribute to the property that you do not want to be serialized.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With