是否可以将Newtonsoft.Json.NullValueHandling.Ignore
用于输出(序列化),而将NullValueHandling.Include
用于输入(反序列化)?
我正在使用ASP.NET Web API构建JSON API。我想从输出中删除不必要的null值,使用以下代码可以轻松做到这一点:
config.Formatters.JsonFormatter.SerializerSettings =
new Newtonsoft.Json.JsonSerializerSettings {
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore
};
但是,在输入时,我想使用NullValueHandling.Include
来包含空值,并在模型对象上触发该属性设置器。
这些属性设置器如下所示:
public long? Foo
{
get { return _Foo; }
set { _Foo = MarkApplied(nameof(Foo), value); }
}
其中MarkApplied
记得Foo
属性是显式设置的。这使我可以分辨出输入JSON对象之间的区别:
{ Foo: 123, Bar: "bar" }
我打算将Foo
属性更新为123
,并将Bar
属性更新为"bar"
,
{ Foo: null, Bar: "bar" }
我打算将Foo
属性更新为null
,将Bar
属性更新为"bar"
,并且
{ Bar: "bar" }
我打算将Bar
属性更新为"bar"
,而不更改Foo
属性的任何内容(与将其设置为null
相对)。
我已经将{{3}}作为一种选择。首先,我真的只希望这种行为适用于空值,而不希望具有有意义的默认值的数字和布尔值。另外,Include
和Ignore
似乎与NullValueHandling
的行为非常匹配,并且Populate
和IgnoreAndPopulate
选项不是我想要的,因为它们即使该属性未包含在输入JSON中,也会触发属性设置器。
答案 0 :(得分:0)
好吧,所以我找到了this StackOverflow post,并且能够创建一个自定义的JsonConverter来完成工作:
public class V2JsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsSubclassOf(typeof(ApiModelBase));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObj = JObject.Load(reader);
var targetObj = (ApiModelBase)Activator.CreateInstance(objectType);
foreach (var prop in objectType.GetProperties().Where(p => p.CanWrite))
{
JToken value;
if (jsonObj.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out value))
{
prop.SetValue(targetObj, value.ToObject(prop.PropertyType, serializer));
}
}
return targetObj;
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}