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:
- 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. - 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
Set Focus on Textbox in Wpf from View Model
How to Replace Multiple Spaces With a Single Space in C#
Show/Hide the Console Window of a C# Console Application
Why Would You Use String.Equals Over ==
Convert Json String to C# Object
How to Write a Simple Html.Dropdownlistfor()
How to Run Servicestack on Linux/Mono
How to Handle Accessviolationexception
Selenium C# Webdriver: Wait Until Element Is Present
How to Check If a Given String Is a Legal/Valid File Name Under Windows
Why and How to Avoid Event Handler Memory Leaks
The Foreach Identifier and Closures
How to Associate a File Extension to the Current Executable in C#