简体   繁体   English

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

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

All, I think I am close with this but I am failing to find the exact class structure that works, please note I can't use JSON.net (sorry I think this is now referred to as newtonsoft json) this needs to be in core .net4.5所有,我想我已经接近了,但我找不到确切的 class 结构,请注意我不能使用 JSON.net (对不起,我认为这现在被称为 newtonsoft json)这需要在 core 中。网4.5

I have a JSON which is similar to this:我有一个类似于此的 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."
                }
            ]
        }
    }

However the messages AB and C could be anything.然而消息 AB 和 C 可以是任何东西。 Therefore as I understand it the notificationMessages is a list of dictionaries?因此,据我了解,notificationMessages 是字典列表吗? However, I don't quite seem to be able to find the syntax that works.但是,我似乎不太能够找到有效的语法。 I'm sure it's something dumb I am missing.我确定这是我想念的愚蠢的东西。 This is what I currently have这是我目前拥有的

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; }

    }

But however, I try and deserialise it and access messages I get an object that is not set...但是,我尝试反序列化它并访问消息,我得到一个未设置的 object...

I have created a fiddle but can't seem to add Script.我创建了一个小提琴,但似乎无法添加脚本。 Serialization I assume as it has been replaced with the latest nuGet but I am restricted to 4.5序列化我假设它已被最新的 nuGet 取代,但我仅限于 4.5

https://dotnetfiddle.net/RjCSim https://dotnetfiddle.net/RjCSim

Edit: Adding answer as provided below编辑:添加答案如下

For my specific scenario this worked:对于我的具体情况,这有效:

  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; }
}

Accessed like:访问方式如下:

            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);
            
            }
        }

You have it mostly sorted but few things to change to make it work.您已经对其进行了大部分排序,但几乎没有什么可以改变以使其正常工作。

{ } is always an object and [ ] is always a list / array. { }始终是 object 并且[ ]始终是列表/数组。 You are trying to deserialize an object to an array which is whats failing.您正在尝试将 object 反序列化为失败的数组。 Following works,继作品之后,

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; }
}

and you can deserialize based on this command using Newtonsoft.Json .您可以using Newtonsoft.Json基于此命令进行反序列化。

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

In your question, notificationMessages is an object (Dictionary of string and Array of Objects).. which is why you have to define it as Dictionary.在您的问题中, notificationMessages是 object(字符串字典和对象数组)。这就是为什么您必须将其定义为字典的原因。 The other thing you will notice is the JsonProperty attribute.您会注意到的另一件事是JsonProperty属性。 C# code standards dictate the first letter of the properties be capital so to work with the json, you have to add the attributes to properly deserialize. C# 代码标准规定属性的第一个字母为大写,因此要使用 json,您必须添加属性以正确反序列化。

If you create a class hierarchy that looks like this (you'll need better class names):如果您创建一个看起来像这样的 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; }
}

and I use the NewtonSoft serializer like this:我像这样使用 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);
}

I get this as output (after formatting):我得到这个 output (格式化后):

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

Which I believe matches what you want.我相信这符合你想要的。 I understand you want to use a different serializer, but this should work with any serializer.我了解您想使用不同的序列化程序,但这应该适用于任何序列化程序。

Note that my class definitions are very different from yours, but mine match what your desired JSON looks like请注意,我的 class 定义与您的定义非常不同,但我的定义与您想要的 JSON 的外观相匹配

==== ====

UPDATE更新

Since you want the "ABC to be variable", change the Outer class to look like:由于您希望“ABC 可变”,因此将Outer class 更改为如下所示:

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

Now, the initialization looks like:现在,初始化看起来像:

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"
                },
            }
        },
    }
};

The serialized output now looks like:序列化的 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"
      }
    ]
  }
}

Once again, the different serializer shouldn't make a difference (I don't work in Core, so you are getting what I can get for you).再一次,不同的序列化程序不应该有所作为(我不在 Core 中工作,所以你得到了我能为你得到的东西)。 Serializers should work round-trip , so you should be able to deserialize this into the the class structure I have provided.序列化程序应该可以往返工作,因此您应该能够将其反序列化为我提供的 class 结构。

To prove my point, this code works:为了证明我的观点,这段代码有效:

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