ren*_*ene 3 c# serialization json.net
我的服务器响应包含一组已知和未知的属性.对于已知的,我创建了一个DTO类,其中包含每个属性的成员.未知属性应放在用[ExtensionData]
属性注释的字典中:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Dto
{
[JsonExtensionData]
private readonly Dictionary<string, object> unknownProperties = new Dictionary<string, object>();
public IDictionary<string, object> UnknownProperties
{
get
{
return new ReadOnlyDictionary<string, object>(this.unknownProperties);
}
}
[JsonProperty(Required = Required.Default, PropertyName = "KNOWN_PROPERTY")]
public string KnownProperty { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
Null
被允许作为值KnownProperty
.如果我尝试反序列化包含的JSON对象,如果我配置了序列化程序,则KNOWN_PROPERTY : null
该属性也包含在字典中.即使存在以下类成员,也会执行此操作:UnknownProperties
NullValueHandling.Ignore
KNOWN_PROPERTY
static void Main(string[] args)
{
string jsonString = @"{
KNOWN_PROPERTY : null,
UNKNOWN_PROPERTY : null
}";
JsonSerializer serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore
});
using (var textReader = new StringReader(jsonString))
{
Dto dto = serializer.Deserialize<Dto>(new JsonTextReader(textReader));
foreach (var pair in dto.UnknownProperties)
{
Console.WriteLine("{0}: {1}", pair.Key, pair.Value == null ? "null" : pair.Value.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
KNOWN_PROPERTY : null
UNKNOWN_PROPERTY : null
Run Code Online (Sandbox Code Playgroud)
如果我在JSON字符串中配置序列化程序NullValueHandling.Include
或为其设置值KNOWN_PROPERTY
,则字典仅包含UNKNOWN_PROPERTY
,如预期的那样.
[ExtensionData]
如果NullValueHandling
设置为忽略,我的理解是无法正常工作,因为文档声明只有在找不到匹配的类成员时才使用扩展.
我看到的行为是什么意思?我可以做些什么来避免这种情况吗?因为我不喜欢向服务器发送空值,所以我想坚持使用当前设置NullValueHandling
.
我正在使用Json.NET 8.0.2
更新
在JsonExtensionData中报告不应包含作为实际对象属性的空值.#1719并在提交e079301中修复.修复程序应该包含在11.0.2之后的Json.NET的下一个版本中.
原始答案
// set extension data if property is ignored or readonly
if (!SetPropertyValue(property, propertyConverter, contract, member, reader, newObject))
{
SetExtensionData(contract, member, reader, memberName, newObject);
}
Run Code Online (Sandbox Code Playgroud)
如果要忽略该属性,则意图似乎是将值放入扩展数据中,但如果要忽略该值,Json.NET会将其放入扩展数据中- 这是一个略有不同的概念.我同意这可能是一个错误.您可能想报告它.
有一个解决方法.Json.NET有两个属性会影响null/default值的序列化:
NullValueHandling
.指定在序列化和反序列化对象时包含或忽略空值.价值观Include
和Ignore
.
DefaultValueHandling
.这有更复杂的语义:
Include
:在序列化对象时包括成员值与成员的默认值相同的成员.包含的成员将写入JSON.反序列化时没有效果.Ignore
:在序列化对象时忽略成员值与成员的默认值相同的成员,这样就不会写入JSON.此选项将忽略所有默认值(例如,对象和可空类型为null;对于整数,小数和浮点数为0;对于布尔值为false).Populate
:反序列化时,具有默认值但没有JSON的成员将设置为其默认值. IgnoreAndPopulate
:在序列化对象时忽略成员值与成员的默认值相同的成员,并在反序列化时将成员设置为其默认值. 那么,这些重叠设置如何相互作用?事实证明,Json.NET同时检查它们:如果两个设置都一致则序列化,如果两个设置都令人满意则反序列化.而且DefaultValueHandling.IgnoreAndPopulate
似乎你想要做什么-序列化时,它忽略了空,但读取和反序列化时,如果存在设置它们.
因此,我能够通过以下方式获得您想要的行为JsonProperty
:
public class Dto
{
[JsonProperty(Required = Required.Default, PropertyName = "KNOWN_PROPERTY", DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, NullValueHandling = NullValueHandling.Include)]
public string KnownProperty { get; private set; }
// Remainder as before.
}
Run Code Online (Sandbox Code Playgroud)
原型小提琴.
归档时间: |
|
查看次数: |
1609 次 |
最近记录: |