繁体   English   中英

如何反序列化具有变量名和数组的 JSON

[英]How do I deserialise a JSON with variable names and an array

所有,我想我已经接近了,但我找不到确切的 class 结构,请注意我不能使用 JSON.net (对不起,我认为这现在被称为 newtonsoft json)这需要在 core 中。网4.5

我有一个类似于此的 JSON:

{"code":"ab", "notificationMessages": {
            "A": [
                {
                    "code": 3010,
                    "message": "The field is required."
                }
            ],
            "B": [
                {
                    "code": 3010,
                    "message": "The field  must be a string or array type with a maximum length of '1'."
                }
            ],
            "C": [
                {
                    "code": 3020,
                    "message": "The  field is required."
                }
            ]
        }
    }

然而消息 AB 和 C 可以是任何东西。 因此,据我了解,notificationMessages 是字典列表吗? 但是,我似乎不太能够找到有效的语法。 我确定这是我想念的愚蠢的东西。 这是我目前拥有的

public class Root
    {
        public string code { get; set; }
        public Notificationmessages notificationMessages { get; set; }
    }

    public class Notificationmessages
    {
        public List<Dictionary<string, MessageArray>> message { get; set; }

    }

    public class MessageArray
    {
        public int code { get; set; }
        public string message { get; set; }

    }

但是,我尝试反序列化它并访问消息,我得到一个未设置的 object...

我创建了一个小提琴,但似乎无法添加脚本。 序列化我假设它已被最新的 nuGet 取代,但我仅限于 4.5

https://dotnetfiddle.net/RjCSim

编辑:添加答案如下

对于我的具体情况,这有效:

  public class RootObj
    {
       
    public string Code { get; set; }
  
    public Dictionary<string, List<NotificationMessage>> NotificationMessages { get; set; }
}
public class NotificationMessage
{       
    public string Code { get; set; }       
    public string Message { get; set; }
}

访问方式如下:

            var result = new JavaScriptSerializer().Deserialize<RootObj>(simpleJson);
        foreach (KeyValuePair<string, List<NotificationMessage>> messages in result.NotificationMessages)
        {

            foreach (NotificationMessage message in messages.Value) {
                Console.WriteLine(message.Message);
            
            }
        }

您已经对其进行了大部分排序,但几乎没有什么可以改变以使其正常工作。

{ }始终是 object 并且[ ]始终是列表/数组。 您正在尝试将 object 反序列化为失败的数组。 继作品之后,

public class RootObj
{
    [JsonProperty("code")]
    public string Code { get; set; }
    [JsonProperty("notificationMessages")]
    public Dictionary<string, List<NotificationMessage>> NotificationMessages { get; set; }
}
public class NotificationMessage
{
    [JsonProperty("code")]
    public string Code { get; set; }
    [JsonProperty("message")]
    public string Message { get; set; }
}

您可以using Newtonsoft.Json基于此命令进行反序列化。

var obj = JsonConvert.DeserializeObject<RootObj>(text);

在您的问题中, notificationMessages是 object(字符串字典和对象数组)。这就是为什么您必须将其定义为字典的原因。 您会注意到的另一件事是JsonProperty属性。 C# 代码标准规定属性的第一个字母为大写,因此要使用 json,您必须添加属性以正确反序列化。

如果您创建一个看起来像这样的 class 层次结构(您需要更好的 class 名称):

public class MessageAndCode
{
    public int code { get; set; }
    public string message { get; set; }
}

public class ABC
{
    public List<MessageAndCode> A { get; set; }
    public List<MessageAndCode> B { get; set; }
    public List<MessageAndCode> C { get; set; }
}

public class Outer
{
    public string code { get; set; }
    public ABC notificationMessages { get; set; }
}

我像这样使用 NewtonSoft 序列化程序:

public static void Test()
{
    var data = new Outer
    {
        code = "ab",
        notificationMessages = new ABC
        {
            A = new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3010,
                    message = "Message A"
                }
            },
            B = new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3015,
                    message = "Message B"
                }
            },
            C = new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3020,
                    message = "Message C"
                }
            }
        }
    };

    var result = JsonConvert.SerializeObject(data);
}

我得到这个 output (格式化后):

{
  "code": "ab",
  "notificationMessages": {
    "A": [
      {
        "code": 3010,
        "message": "Message A"
      }
    ],
    "B": [
      {
        "code": 3015,
        "message": "Message B"
      }
    ],
    "C": [
      {
        "code": 3020,
        "message": "Message C"
      }
    ]
  }
}

我相信这符合你想要的。 我了解您想使用不同的序列化程序,但这应该适用于任何序列化程序。

请注意,我的 class 定义与您的定义非常不同,但我的定义与您想要的 JSON 的外观相匹配

====

更新

由于您希望“ABC 可变”,因此将Outer class 更改为如下所示:

public class Outer2
{
    public string code { get; set; }
    public Dictionary<string, List<MessageAndCode>> notificationMessages { get; set; }
}

现在,初始化看起来像:

var data2 = new Outer2
{
    code = "ab",
    notificationMessages = new Dictionary<string, List<MessageAndCode>>
    {
        {
            "A", new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3010,
                    message = "Message A"
                },
            }
        },
        {
            "B", new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3020,
                    message = "Message B"
                },
            }
        },
        {
            "C", new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3030,
                    message = "Message C"
                },
            }
        },
        {
            "Bonus", new List<MessageAndCode>
            {
                new MessageAndCode
                {
                    code = 3040,
                    message = "Message Bonus"
                },
            }
        },
    }
};

序列化的 output 现在看起来像:

{
  "code": "ab",
  "notificationMessages": {
    "A": [
      {
        "code": 3010,
        "message": "Message A"
      }
    ],
    "B": [
      {
        "code": 3020,
        "message": "Message B"
      }
    ],
    "C": [
      {
        "code": 3030,
        "message": "Message C"
      }
    ],
    "Bonus": [
      {
        "code": 3040,
        "message": "Message Bonus"
      }
    ]
  }
}

再一次,不同的序列化程序不应该有所作为(我不在 Core 中工作,所以你得到了我能为你得到的东西)。 序列化程序应该可以往返工作,因此您应该能够将其反序列化为我提供的 class 结构。

为了证明我的观点,这段代码有效:

var result = JsonConvert.SerializeObject(data2);
var deserialize = JsonConvert.DeserializeObject<Outer2>(result);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM