I would like to serialize only certain properties of an object using Json.NET.
I'm using a solution like the one described in the post Json.net serialize only certain properties.
My problem is that I would like to select different properties each time, and calls to CreateContract
(which in turn calls CreateProperties
) are being cached for performance reasons (source code: https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs).
Is there a way to serialize only the properties I want, specifying different properties each time, possibly without re-writing the whole DefaultContractResolver
class?
Here is a program that shows this problem:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
class Person {
public int Id;
public string FirstName;
public string LastName;
}
public class SelectedPropertiesContractResolver<T> : CamelCasePropertyNamesContractResolver {
HashSet<string> _selectedProperties;
public SelectedPropertiesContractResolver(IEnumerable<string> selectedProperties) {
_selectedProperties = selectedProperties.ToHashSet();
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
if (type == typeof(T)) {
return base.CreateProperties(type, memberSerialization)
.Where(p => _selectedProperties.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)).ToList();
}
return base.CreateProperties(type, memberSerialization);
}
}
class Program {
static void Main(string[] args) {
var person = new Person { Id = 1, FirstName = "John", LastName = "Doe" };
var serializer1 = new JsonSerializer {
ContractResolver = new SelectedPropertiesContractResolver<Person>(new[] { "Id", "FirstName" })
};
// This will contain only Id and FirstName, as expected
string json1 = JObject.FromObject(person, serializer1).ToString();
var serializer2 = new JsonSerializer {
ContractResolver = new SelectedPropertiesContractResolver<Person>(new[] { "LastName" })
};
// Since calls to CreateProperties are cached, this will contain Id and FirstName as well, instead of LastName.
string json2 = JObject.FromObject(person, serializer2).ToString();
}
}