[英]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.