JSon.Net具体的JSonConverter问题,必须忽略空数组

时间:2017-04-06 18:47:35

标签: serialization json.net

我注意到序列化中的奇怪行为。 虽然,我有设置

var SerializerSettings = new JsonSerializerSettings() {
                   NullValueHandling = NullValueHandling.Ignore,     DefaultValueHandling= DefaultValueHandling.Ignore}
SerializerSettings.Converters.Add(new JsonArrayToNullConverter());

  var val = new company()
   {
       name = "Bobo Company Renamed"
   }
 var str = JsonConvert.SerializeObject(val, SerializerSettings );

结果将是: {" document_type":2," locations":null,...

没有自定义转换器,它会 {" document_type":2," locations":[],...

你明白了吗?

但是,因为它变为null,它应该 - 听NullValueHandling = NullValueHandling.Ignore 但显然,Newton会查看要序列化的对象值,而不是发布的 writer.WriteNull ();

:(

任何解决方法?我在这上面花了几个小时。谢谢!

using Newtonsoft.Json;

using System;
using System.Collections;
using System.Collections.Generic;

namespace Company.Model.TypeConverters
{
    /// <summary>
    /// undo's the forced array creation because OData needs it, but for PATCH, we want no [] empty collections, it is considered to be a 
    /// </summary>
    public class JsonArrayToNullConverter : JsonConverter
    {

        public override bool CanConvert(Type objectType)
        {
            var canConvert = objectType.IsArray || (objectType.IsGenericType && objectType.GetGenericTypeDefinition().IsAssignableFrom(typeof(IEnumerable<>)));
            return canConvert;
        }
        public override bool CanRead
        {
            get
            {
                return false;
            }
        }
        public override bool CanWrite
        {
            get
            {
                return true;
            }
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var enumerator = (IEnumerable)value;

            if (enumerator != null && enumerator.GetEnumerator().MoveNext() == false)
            {
                writer.WriteNull();
                //value = null;
                return;
            }
            serializer.Serialize(writer, value);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案似乎是使用了契约解析器并在JsonSerializerSettings上设置了它。

 public class NullToEmptyListResolver : DefaultContractResolver
{
    protected override IValueProvider CreateMemberValueProvider(MemberInfo member)
    {
        IValueProvider provider = base.CreateMemberValueProvider(member);

        if (member.MemberType == MemberTypes.Property)
        {
            Type propType = ((PropertyInfo)member).PropertyType;
            if (propType.IsArray || ( propType.IsGenericType &&
                propType.GetGenericTypeDefinition().IsAssignableFrom(typeof(IEnumerable<>))))
            {
                return new EmptyListValueProvider(provider, propType);
            }
        }

        return provider;
    }

    public class EmptyListValueProvider : IValueProvider
    {
        private readonly IValueProvider innerProvider;

        public EmptyListValueProvider(IValueProvider innerProvider, Type listType)
        {
            this.innerProvider = innerProvider;
        }

        public void SetValue(object target, object value)
        {
            throw new NotImplementedException();
        }

        public object GetValue(object target)
        {
            var val = innerProvider.GetValue(target) ;
            if (val == null) return null;
            var enumerator = (IEnumerable)val;
            return enumerator.GetEnumerator().MoveNext() == false ? null : val;
        }
    }