tags:

views:

96

answers:

2

Hi,

I have just updated my version of NewtonSoft JSON.NET from version 3.0.0 to 3.5.0 and I have noticed that protected members are not implicitly serialised.

I have the following class:

public class SimpleFileContainer : IDto
{
    public virtual string Name { get; protected set; }

    public virtual string Path { get; protected set; }

    public SimpleFileContainer(string name, string path)
    {
        Name = name;
        Path = path;
    }
}

The following test code does not pass

var json = JsonConvert.SerializeObject(new SimpleFileContainer("Name", "Path"));

var deserialised = JsonConvert.DeserializeObject<SimpleFileContainer >(json);

Assert.That(deserialised.Name, Is.EqualTo("Name");

both the Name and Path properties are null unless I either make the property sets public or add update the class with the following attributes:

[JsonObject(MemberSerialization.OptOut)]
public class SimpleFileContainer : IDto
{
    [JsonProperty]
    public virtual string Name { get; protected set; }

    [JsonProperty]
    public virtual string Path { get; protected set; }

    public SimpleFileContainer(string name, string path)
    {
        Name = name;
        Path = path;
    }
}

This is a reasonably sized project that uses the serialization process a lot, I do not want to go through the code adding these attributes to every class and member.

Is there a way round this?

Cheers

Paul

A: 

The best thing to do is downgrade back to the older version. There is always a risk that an upgrade changes behaviors in a way detrimental to your project. If so, don't use the upgrade.

Matthew Ferreira
I want to use new functionality that is in the latest version.
dagda1
+1  A: 

I had this same problem today. Luckily Ayende had the fix and I am sharing it with you. When you configure the serializer, change the DefaultMembersSearchFlags property on the ContractResolver:

var serializer = new JsonSerializer
                        {
                            ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                            ContractResolver = new DefaultContractResolver
                                {
                                    DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
                                },
                            TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,

                            ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
                        };
João Bragança