Met*_*uru 7 arrays null default list json.net
目前我有JSON,它通过HTTP调用进入或存储在数据库中,但在服务器处理期间,它们被映射到C#对象.
这些对象具有类似的属性public List<int> MyArray.
当JSON包含时,MyArray:null我希望结果属性为空List<T>而不是null List<T>属性.
目标是该对象将"重新序列化"为JSON MyArray:[],因此要么保存到数据库,要么通过HTTP作为空数组而不是null.
这样,无论如何,C#类基本上都是为任何List<T>属性进行清理并强制执行一个空数组,否则会null导致浏览器端代码中断(例如:) cannot read property 'length' of null.
有没有一种方法,在序列化/反序列化过程中,我可以将任何与List<T>属性配对的空值变为空数组?
如果null为空,你总是可以延迟加载一个空列表.
要么
在JsonDeserializer上使用NullValueHandling选项.
var settings = new JsonSerializerSettings();
settings.NullValueHandling = NullValueHandling.Ignore;
return JsonConvert.DeserializeObject<T>(json, settings);
Run Code Online (Sandbox Code Playgroud)
http://james.newtonking.com/json/help/index.html?topic=html/SerializationSettings.htm
以下属性将在反序列化后为其分配空集合,而不是null在这两种情况下:当在 JSON 中省略该属性或显式设置时null:
class A
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public IEnumerable<int> Prop { get; set; } = new List<int>();
}
Run Code Online (Sandbox Code Playgroud)
我打算建议使用自定义JsonConverter来解决这个问题,但转换器不会被调用null值.相反,您需要将自定义IContractResolver与自定义结合使用IValueProvider.以下是您需要的代码(受此答案的启发):
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.IsGenericType &&
propType.GetGenericTypeDefinition() == typeof(List<>))
{
return new EmptyListValueProvider(provider, propType);
}
}
return provider;
}
class EmptyListValueProvider : IValueProvider
{
private IValueProvider innerProvider;
private object defaultValue;
public EmptyListValueProvider(IValueProvider innerProvider, Type listType)
{
this.innerProvider = innerProvider;
defaultValue = Activator.CreateInstance(listType);
}
public void SetValue(object target, object value)
{
innerProvider.SetValue(target, value ?? defaultValue);
}
public object GetValue(object target)
{
return innerProvider.GetValue(target) ?? defaultValue;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个演示如何使用解析器的演示:
class Program
{
static void Main(string[] args)
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new NullToEmptyListResolver();
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
settings.Formatting = Formatting.Indented;
Console.WriteLine("Serializing object with null lists...");
Foo foo = new Foo();
string json = JsonConvert.SerializeObject(foo, settings);
Console.WriteLine(json);
Console.WriteLine();
Console.WriteLine("Deserializing JSON with null lists...");
json = @"{ ""IntList"" : null, ""StringList"" : null }";
foo = JsonConvert.DeserializeObject<Foo>(json, settings);
Console.WriteLine("IntList size: " + foo.IntList.Count);
Console.WriteLine("StringList size: " + foo.StringList.Count);
}
}
class Foo
{
public List<int> IntList { get; set; }
public List<string> StringList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
输出:
Serializing object with null lists...
{
"IntList": [],
"StringList": []
}
Deserializing JSON with null lists...
IntList size: 0
StringList size: 0
Run Code Online (Sandbox Code Playgroud)