How to Exclude Property from Json Serialization

How to exclude property from Json Serialization

If you are using Json.Net attribute [JsonIgnore] will simply ignore the field/property while serializing or deserialising.

public class Car
{
// included in JSON
public string Model { get; set; }
public DateTime Year { get; set; }
public List<string> Features { get; set; }

// ignored
[JsonIgnore]
public DateTime LastModified { get; set; }
}

Or you can use DataContract and DataMember attribute to selectively serialize/deserialize properties/fields.

[DataContract]
public class Computer
{
// included in JSON
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal SalePrice { get; set; }

// ignored
public string Manufacture { get; set; }
public int StockCount { get; set; }
public decimal WholeSalePrice { get; set; }
public DateTime NextShipmentDate { get; set; }
}

Refer http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size for more details

How to exclude a property from being serialized in System.Text.Json.JsonSerializer.Serialize() using a JsonConverter

So I happened to stumble upon an article that demonstrates how to use the JsonDocument object in the new System.Text.Json namespace and it is the next best thing to a Fluent API. Here is how this question can be solved.

The BookConverter.Write() method:

public override void Write(Utf8JsonWriter writer, Book value, JsonSerializerOptions options)
{
writer.WriteStartObject();

using (JsonDocument document = JsonDocument.Parse(JsonSerializer.Serialize(value)))
{
foreach (var property in document.RootElement.EnumerateObject())
{
if (property.Name != "Author")
property.WriteTo(writer);
}
}

writer.WriteEndObject();
}

How to exclude specific type from json serialization

The following allows you to exclude a specific data-type that you want excluded from the resulting json. It's quite simple to use and implement and was adapted from the link at the bottom.

You can use this as you cant alter the actual classes:

public class DynamicContractResolver : DefaultContractResolver
{

private Type _typeToIgnore;
public DynamicContractResolver(Type typeToIgnore)
{
_typeToIgnore = typeToIgnore;
}

protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);

properties = properties.Where(p => p.PropertyType != _typeToIgnore).ToList();

return properties;
}
}

Usage and sample:

public class MyClass
{
public string Name { get; set; }
public byte[] MyBytes1 { get; set; }
public byte[] MyBytes2 { get; set; }
}

MyClass m = new MyClass
{
Name = "Test",
MyBytes1 = System.Text.Encoding.Default.GetBytes("Test1"),
MyBytes2 = System.Text.Encoding.Default.GetBytes("Test2")
};



JsonConvert.SerializeObject(m, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new DynamicContractResolver(typeof(byte[])) });

Output:

{
"Name": "Test"
}

More information can be found here:

Reducing Serialized JSON Size

Exclude executable property from JSON serialization

Try this code (serialize only get-set properties):

public static class NewtonsoftDefaultSettings
{
public static JsonSerializerSettings CreateRelease()
{
return Create(Formatting.None);
}

public static JsonSerializerSettings CreateDebug()
{
return Create(Formatting.Indented);
}

private static JsonSerializerSettings Create(Formatting formatting)
{
return new JsonSerializerSettings
{
Formatting = formatting,
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = new MyContractResolver()
};
}
}

internal class MyContractResolver : DefaultContractResolver
{
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
var members = base.GetSerializableMembers(objectType).Cast<PropertyInfo>().ToList();
members.RemoveAll(x => !x.CanRead || !x.CanWrite);
return members.Cast<MemberInfo>().ToList();
}
}

And finally:

var str = JsonConvert.SerializeObject(value, NewtonsoftDefaultSettings.CreateDebug());

Python JSON serialize excluding certain fields

I can think of three solutions for your situation:

Solution 1:
Use Pykson third party library and define the fields you want to be serialized as pykson fields.

Sample:

class MyItemClass(pykson.JsonObject):
saved_property = pykson.IntegerField()

my_object = MyItemClass(saved_property=1, accept_unknown=True)
my_object.unsaved_property = 2
pykson.Pykson().to_json(my_object)

disclaimer: I am developer of pykson library.

Solution 2:
The second solution is to use a wrapper class with custom default deserializer.

class ObjectWrapper:
def __init__(self, value, should_serialize=False)
self.value = value
self.should_serialize = should_serialize

def default_handler(obj):
if isinstance(obj, ObjectWrapper):
if obj.should_serialize:
return obj.value
else:
return None
else:
raise TypeError

json.dump(default=default_handler)

Solution 3:
It might be a bad idea but if you have a in case of deep hierarchy, you can also add a function to allc classes which will be serialized and use this function to get a dictionary and easily convert the dictionary to json.

class MyChildClass:
def __init__(self, serialized_property, not_serialized_property):
self.serialized_property = serialized_property
self.not_serialized_property = not_serialized_property

def to_dict(self):
# only add serialized property here
return {
"serialized_property": self.serialized_property
}

class MyParentClass:
def __init__(self, child_property, some_other_property):
self.child_property = child_property
self.some_other_property = some_other_property

def to_dict(self):
return {
'child_property': self.child_property.to_dict(),
'some_other_property': self.some_other_property
}

my_child_object = MyChildClass(serialized_property=1, not_serialized_property=2)
my_parent_object = MyParentClass(child_property=my_child_object, some_other_property='some string here')
json.dumps(my_parent_object.to_dict())

Or you can achieve same result using default handler:

class MyChildClass:
def __init__(self, serialized_property, not_serialized_property):
self.serialized_property = serialized_property
self.not_serialized_property = not_serialized_property

def to_dict(self):
# only add serialized property here
return {
"serialized_property": self.serialized_property
}

class MyParentClass:
def __init__(self, child_property, some_other_property):
self.child_property = child_property
self.some_other_property = some_other_property

def to_dict(self):
return {
'child_property': self.child_property,
'some_other_property': self.some_other_property
}

def handle_default(obj):
if isinstance(obj, MyChildClass):
return obj.to_dict()
elif isinstance(obj, MyParentClass):
return obj.to_dict()
return None

my_child_object = MyChildClass(serialized_property=1, not_serialized_property=2)
my_parent_object = MyParentClass(child_property=my_child_object, some_other_property='some string here')
json.dumps(my_parent_object, default=handle_default)

Choose class properties to include/exclude for JSON serialization

For the record

As Peter Csala suggested, I ended up using JsonConverter
It work perfectly with what I need.

The concept is:

public class BaseTypeOnlyConverter<T> : JsonConverter<T>
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
writer.WriteStartObject();

var t = value.GetType();

var propertiesName = t.GetProperties()
.Where(o => ShouldInclude(o))
.Select(o => o.Name.ToLower())
.ToList();

using (var document = JsonDocument.Parse(JsonSerializer.Serialize(value)))
{
foreach (var property in document.RootElement.EnumerateObject())
{
if (propertiesName.Contains(property.Name.ToLower()))
property.WriteTo(writer);
}
}

writer.WriteEndObject();
}

private bool ShouldInclude(PropertyInfo propertyInfo)
{
//Do checkup ...
}
}

Exclude property from serialization via custom attribute (json.net)

You have a few options. I recommend you read the Json.Net documentation article on the subject before reading below.

The article presents two methods:

  1. Create a method that returns a bool value based on a naming convention that Json.Net will follow to determine whether or not to serialize the property.
  2. Create a custom contract resolver that ignores the property.

Of the two, I favor the latter. Skip attributes altogether -- only use them to ignore properties across all forms of serialization. Instead, create a custom contract resolver that ignores the property in question, and only use the contract resolver when you want to ignore the property, leaving other users of the class free to serialize the property or not at their own whim.

Edit To avoid link rot, I'm posting the code in question from the article

public class ShouldSerializeContractResolver : DefaultContractResolver
{
public new static readonly ShouldSerializeContractResolver Instance =
new ShouldSerializeContractResolver();

protected override JsonProperty CreateProperty( MemberInfo member,
MemberSerialization memberSerialization )
{
JsonProperty property = base.CreateProperty( member, memberSerialization );

if( property.DeclaringType == typeof(Employee) &&
property.PropertyName == "Manager" )
{
property.ShouldSerialize = instance =>
{
// replace this logic with your own, probably just
// return false;
Employee e = (Employee)instance;
return e.Manager != e;
};
}

return property;
}
}


Related Topics



Leave a reply



Submit