Reputation: 177
I'm struggling with conditionally serializing a property of an object that is a property of another object itself. Consider the following class structure:
public class Message
{
public string Content { get; set; }
public IEnumerable<Attachment> Attachments { get; set; }
}
public class Attachment
{
public string Base64Content { get; set; }
public string FileName { get; set; }
}
In some scenarios I want to serialize everything in the Message
class, including all Attachment
objects and its properties. This can be done by using a simple JsonConvert.SerializeObject()
. If I always wanted to ignore the Base64Content
property, I could just add a '[JsonIgnore]' attribute on that property. However, there are some scenarios in which I want the Base64Content
serialized, and in others I don't.
I though about creating a custom ContractResolver
that ignores the Attachments
property of the Message
object. But of course, this ignores the whole list of Attachment
objects and not just the Base64Content
property.
Is there a way of writing a ContractResolver
class that lets me ignore the Base64Content
property when serializing the Message
object?
Upvotes: 5
Views: 3179
Reputation: 875
Just create a custom contract resolver which excludes the properties passed to it while serializing and pass the Base64Content
property in it conditionally.
public class CustomPropertiesContractResolver : DefaultContractResolver
{
private HashSet<string> _propertySet;
public CustomPropertiesContractResolver(IEnumerable<string> propertyNames)
{
if (propertyNames != null)
{
_propertySet = new HashSet<string>(propertyNames, StringComparer.OrdinalIgnoreCase);
}
}
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
{
List<MemberInfo> serializableMembers = null;
var allMembers = base.GetSerializableMembers(objectType);
if (_propertySet != null && _propertySet.Count > 0)
{
serializableMembers = allMembers.Where(m => !_propertySet.Contains(m.Name)).ToList();
}
return serializableMembers != null && serializableMembers.Count > 0 ? serializableMembers : allMembers;
}
}
use it like:
IEnumerable<string> properties = null;
if (condition)
{
properties = new List<string> { "Base64Content" };
}
var settings = new JsonSerializerSettings()
{
ContractResolver = new CustomPropertiesContractResolver(properties)
};
var serializedStr = JsonConvert.SerializeObject(messages, settings);
Upvotes: 3