【问题标题】:Json.NET deserializing nested object ignores JsonProperty.RequiredJson.NET 反序列化嵌套对象忽略 JsonProperty.Required
【发布时间】:2017-07-29 14:36:01
【问题描述】:

当反序列化带有嵌套对象的 JSON 对象时,其中一个嵌套对象具有必需的属性,反序列化不会引发异常。但是,如果我将 JsonProperty.Required 装饰添加到基础对象中,它会这样做(正如我所期望的那样)。当输入字符串的类型完全错误,但格式正确的 JSON 时,就会发生这种情况。

所以,有问题的输入是 "{\"Errors\":[\"This is an error\"]}" (这是来自网络服务的响应,或者是这样的错误消息数组,或者是正确序列化的 UserInformationRequest)。 代码澄清:

基础对象 JsonProperty 正常运行:

    public class UserInformation
    {
        public string ID;
        ...
        public string LoginName;
        ...
    }

    public class UserInformationRequest
    {
        [JsonProperty(Required = Required.Always)]
        public string TimeStamp;
        public UserInformation User;
    }
    ...
    public static UserInformationRequest GetUserInformationRequestFromString(string userInformation)
    {
        try
        {
            return JsonConvert.DeserializeObject<UserRequestInformation>(userInformation);
        }
        catch (Exception ex)
        {
            //exception thrown when userInformation.TimeStamp is null, as expected
            return null;
        }
    }

嵌套的 JsonProperty 无法正常运行:

    public class UserInformation
    {
        public string ID;
        ...
        [JsonProperty(Required = Required.Always)]
        public string LoginName;
        ...
    }

    public class UserInformationRequest
    {
        public string TimeStamp;
        public UserInformation User;
    }
    ...
    public static UserInformationRequest GetUserInformationRequestFromString(string userInformation)
    {
        try
        {
            return JsonConvert.DeserializeObject<UserRequestInformation>(userInformation);
        }
        catch (Exception ex)
        {
            //never gets here - no exception thrown if userInformation.User.LoginName is null
            return null;
        }
    }

鉴于此,当尝试将 Errors 数组反序列化为 UserInformationRequest 时,如果基础对象上有 JsonProperty,则会正确抛出异常,但如果嵌套对象包含 JsonProperty,则永远不会抛出异常。

演示该问题的工作 dotnetfiddles: 基础对象上的 JsonProperty:https://dotnetfiddle.net/qvyPfP 嵌套对象上的 JsonProperty:https://dotnetfiddle.net/M3F0rb

【问题讨论】:

  • 能否显示在“GetUserInformationRequestFromString”方法中作为参数接收的“userInformation”json 字符串?
  • @emkayultra,您在哪个版本的 .Net 和 Json.Net 中看到了这个问题?
  • @JonLopezGarcia - 第一个例子:"{\"TimeStamp\":null,\"User\":{\"ID\":12345,\"LoginName\":\"username\" }}"} 和第二个例子:"{\"TimeStamp\":\"2017-07-29 10:31:53\",\"User\":{\"ID\":12345,\"LoginName\ ":null}}"
  • @AlDass - .NET 4.5,Json.NET 10.0.3
  • 我正在更新这个问题,因为在挖掘之后它比这更复杂一些。

标签: c# .net json json.net json-deserialization


【解决方案1】:

如果您还使用[JsonProperty(Required = Required.Always)] 属性标记UserInformationRequest 类中的User 属性,则反序列化程序似乎会在UserInformation 内部查找LoginName 成员不是所要求的null .

Here 您的第二个示例具有 User 属性上的属性

【讨论】:

  • 看起来它确实解决了这个问题。但是,如果我不希望 User 被要求,但如果 User 确实提供了,那么它必须有 LoginName
  • 好吧,如果我们仔细考虑,这正是发生的事情。如果您提供 User 属性并且所需属性位于 LoginName 属性上,则会引发异常。见here。如果您不提供关于 json 字符串中的 User 属性的任何内容,则反序列化器将完全忽略类中的字段。如果您不希望行为如此,并强制反序列化器处理 json 中的 User 属性,则意味着您希望填写该字段(换句话说,需要)。使用必需的属性
  • 有道理,感谢您的帮助和澄清。将您的答案标记为“the”答案。
猜你喜欢
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 2014-02-19
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
相关资源
最近更新 更多