Search code examples
c#json.net

Private setters in Json.Net


I know there's an attribute to handle private setters but I kind of want this behavior as a default, is there a way to accomplish this? Except tweaking the source. Would be great if there was a setting for this.


Solution

  • 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/