如何取消对带有变量名和数组的JSON的序列化



全部,我想我已经接近了,但我找不到确切的类结构,请注意,我不能使用JSON.net(对不起,我认为这现在被称为newtonsoft-JSON(,这需要在core.net4.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."
}
]
}
}

然而,消息A、B和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; }
}

但是,我尝试取消它的序列化并访问消息,我得到了一个未设置的对象。。。

我已经创建了一个小提琴,但似乎无法添加脚本。序列化我认为它已经被最新的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);

}
}

您已经对其进行了大部分排序,但很少需要更改才能使其工作。

{ }总是一个对象,而[ ]总是一个列表/数组。您正试图将对象反序列化为数组,这是失败的原因。以下工作,

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是一个对象(字符串字典和对象数组(。。这就是为什么你必须把它定义为Dictionary。您将注意到的另一件事是JsonProperty属性。C#代码标准规定属性的第一个字母是大写的,因此要使用json,必须添加要正确反序列化的属性。

如果你创建了一个类似这样的类层次结构(你需要更好的类名(:

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

我得到的输出(格式化后(:

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

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

请注意,我的类定义与您的类定义非常不同,但我的定义与您想要的JSON看起来像相匹配

===

更新

既然你想要";ABC是可变的";,将Outer类更改为:

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

串行输出现在看起来像:

{
"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工作,所以你得到了我能为你得到的(。序列化程序应该工作往返,因此您应该能够将其反序列化为我提供的类结构。

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

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

最新更新