我注意到序列化中的奇怪行为。虽然,我有设置
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,"位置":空, ...
如果没有自定义转换器,它将是{"document_type":2,"位置":[], ...
你明白了吗?
但是,由于它变为 null,它应该侦听 NullValueHandling = NullValueHandling.Ignore但显然,Newton 查看的是要序列化的对象值,而不是发布的编写器。写空((;
:(
有什么解决方法吗?我为此花了几个小时。谢谢!
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);
}
}
}
解决方案似乎是使用合同解析器并将其设置为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;
}
}