Private setters in Json.Net
I came here looking for the actual attribute that makes Json.NET populate a readonly property when deserializing, and that's simply [JsonProperty]
, e.g.:
[JsonProperty]
public Guid? ClientId { get; private set; }
Alternative Solution
Just provide a constructor that has a parameter matching your property:
public class Foo
{
public string Bar { get; }
public Foo(string bar)
{
Bar = bar;
}
}
Now this works:
string json = "{ \"bar\": \"Stack Overflow\" }";
var deserialized = JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine(deserialized.Bar); // Stack Overflow
I prefer this approach where possible since:
- It doesn't require you to decorate your properties with attributes.
- It works with both
{ get; private set; }
and just{ get; }
.
Updated, new answer
I've written a source distribution NuGet for this, that installs a single file with two custom contract resolvers:
- PrivateSetterContractResolver
- PrivateSetterCamelCasePropertyNamesContractResolver
Install the NuGet package:
Install-Package JsonNet.ContractResolvers
Then just use any of the resolvers:
var settings = new JsonSerializerSettings
{
ContractResolver = new PrivateSetterContractResolver()
};
var model = JsonConvert.DeserializeObject<Model>(json, settings);
You can read about it here: http://danielwertheim.se/json-net-private-setters-nuget/
GitHub repo: https://github.com/danielwertheim/jsonnet-privatesetterscontractresolvers
Old answer (still valid)
There are two alternatives that can solve the problem.
Alt 1: On the deserializers
ContractResolver.DefaultMembersSearchFlags =
DefaultMembersSearchFlags | BindingFlags.NonPublic;
The default serialization option supports all types of class member. Therefore this solution will return all private members types including fields. I'm only interested in also supporting private setters.
Alt2: Create a custom ContractResolver:
Therefore this is the better options since we just check the properties.
public class SisoJsonDefaultContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(
MemberInfo member,
MemberSerialization memberSerialization)
{
//TODO: Maybe cache
var prop = base.CreateProperty(member, memberSerialization);
if (!prop.Writable)
{
var property = member as PropertyInfo;
if (property != null)
{
var hasPrivateSetter = property.GetSetMethod(true) != null;
prop.Writable = hasPrivateSetter;
}
}
return prop;
}
}
For more information, read my post: http://danielwertheim.se/json-net-private-setters/