2

I am using JSON.NET to serialize a class to JSON. The class contains a property which consists of a list of items, and I want to serialize the items themselves in a custom way (by dynamically including only certain properties, using a customized ContractResolver). So basically I want to serialize the parent class itself in a standard way, with the DefaultContractResolver, but serialize this one property in a custom way, with my own ContractResolver.

JSON.NET has methods that probably allow this but the documentation is rather sketchy. Any help would be appreciated.

2 Answers 2

2

I solved this problem with a ContractResolver. The list of objects that I want to serialize is heterogeneous, so I have to pass it two arguments, a list of properties to be serialized, and a list of types to which the property list applies. So it looks like this:

    public class DynamicContractResolver : DefaultContractResolver
    {
        private List<string> mPropertiesToSerialize = null;
        private List<string> mItemTypeNames = new List<string>();

        public DynamicContractResolver( List<string> propertiesToSerialize,
            List<string> itemTypeNames )
        {
            this.mPropertiesToSerialize = propertiesToSerialize;
            this.mItemTypeNames = itemTypeNames;
        }

        protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization )
        {
            IList<JsonProperty> properties = base.CreateProperties( type, memberSerialization );
            if( this.mItemTypeNames.Contains( type.Name ) )
                properties = properties.Where( p => mPropertiesToSerialize.Contains( p.PropertyName ) ).ToList();
            return properties;
        }
    }

And it is called like this:

            DynamicContractResolver contractResolver = new DynamicContractResolver( propsToSerialize, GetItemTypeNames() );
            json = JsonConvert.SerializeObject( this, Formatting.None,
                new JsonSerializerSettings { ContractResolver = contractResolver } );

where GetItemTypeNames() calls GetType().Name on each of the items in the list that I want to serialize and writes them distinctly to a list.

Sorry my original question was vague and badly phrased, and if somebody has a better solution I am certainly not wedded to this one.

Sign up to request clarification or add additional context in comments.

Comments

0

Here's a version that's a bit better. It associates type names with properties, so you can specify which properties you wish to have serialized at every level. The keys to the dictionary are type names; the value is a list of properties to be serialized for each type.

class PropertyContractResolver : DefaultContractResolver
{
    public PropertyContractResolver( Dictionary<string, IEnumerable<string>> propsByType )  
    {
        PropertiesByType = propsByType;
    }

    protected override IList<JsonProperty> CreateProperties( Type type, MemberSerialization memberSerialization )
    {
        IList<JsonProperty> properties = base.CreateProperties( type, memberSerialization );
        if( this.PropertiesByType.ContainsKey( type.Name ) )
        {
            IEnumerable<string> propsToSerialize = this.PropertiesByType[ type.Name ];
            properties = properties.Where( p => propsToSerialize.Contains( p.PropertyName ) ).ToList();
        }
        return properties;
    }

    private Dictionary<string, IEnumerable<string>> PropertiesByType
    {
        get;
        set;
    }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.