Add Multiple Contract Resolver in Newtonsoft.Json

后端 未结 3 472
名媛妹妹
名媛妹妹 2020-12-17 15:16

Blueprint for data structure:

public class Movie
{
    public string Name { get; set; }
}

Using Newtonsoft.Json, I have the following confi

3条回答
  •  情深已故
    2020-12-17 15:33

    I find it's a much better idea to create a composite-contract-resolver. This is what I use in my projects:

    public class CompositeContractResolver : IContractResolver, IEnumerable
    {
        private readonly IList _contractResolvers = new List();
    
        public JsonContract ResolveContract(Type type)
        {
            return
                _contractResolvers
                    .Select(x => x.ResolveContract(type))
                    .FirstOrDefault(Conditional.IsNotNull);
        }
    
        public void Add([NotNull] IContractResolver contractResolver)
        {
            if (contractResolver == null) throw new ArgumentNullException(nameof(contractResolver));
            _contractResolvers.Add(contractResolver);
        }
    
        public IEnumerator GetEnumerator()
        {
            return _contractResolvers.GetEnumerator();
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    

    I then use it like this:

    Settings = new JsonSerializerSettings
    {
        ContractResolver = new CompositeContractResolver
        {
            new InterfaceContractResolver(),
            new DefaultContractResolver()
        }
    }
    

    where my custom contract-resolvers return a null contract so the composite one can fall through the default one if there is no match.

    public class InterfaceContractResolver : DefaultContractResolver
    {
        public InterfaceContractResolver()
        {
            if (!typeof(T).IsInterface) throw new InvalidOperationException("T must be an interface.");
        }
    
        public override JsonContract ResolveContract(Type type)
        {
            return 
                typeof(T).IsAssignableFrom(type) 
                    ? base.ResolveContract(typeof(T)) 
                    : default;
        }
    
        protected override IList CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            return
                typeof(T).IsAssignableFrom(type)
                    ? base.CreateProperties(typeof(T), memberSerialization)
                    : default;
        }
    }
    

提交回复
热议问题