使用 C# 返回具有重复键的 Json 对象
Posted
技术标签:
【中文标题】使用 C# 返回具有重复键的 Json 对象【英文标题】:Return Json object with Duplicate Keys using C# 【发布时间】:2017-07-12 02:14:49 【问题描述】:我正在使用 WEB API 接收来自客户端应用程序的保存联系信息的请求,并且只有在数据有错误时才需要发送错误消息;否则没有待办事项
之前我用过字典
例如:
Dictionary<string, string> error = new Dictionary<string, string>
"SaveContactMethod_1", "FirstName Invalid",
"SaveContactMethod_2", "LastName Invalid",
"SaveContactMethod_3", "MiddleName Invalid",
相应的 JSON 对象是
"error" :
"SaveContactMethod_1":"FirstName Invalid",
"SaveContactMethod_2":"LastName Invalid",
"SaveContactMethod_3":"MiddleName Invalid"
但我需要一个唯一密钥(即重复密钥),所以我将Dictionary<string, string>
更改为List<KeyValuePair<string, string>>
List<KeyValuePair<string, string>> error = new List<KeyValuePair<string, string>>
new KeyValuePair<string, string>("SaveContactMethod", "FirstName Invalid"),
new KeyValuePair<string, string>("SaveContactMethod", "LastName Invalid"),
new KeyValuePair<string, string>("SaveContactMethod", "MiddleName Invalid"),
相应的 JSON 对象是
"error" : [
"key":"SaveContactMethod", "value":"FirstName Invalid" ,
"key":"SaveContactMethod", "value":"LastName Invalid" ,
"key":"SaveContactMethod", "value":"MiddleName Invalid"
]
我的要求:我需要添加一个重复键,我需要像字典一样的 Json 输出。
预期输出:JSON
"error" :
"SaveContactMethod":"FirstName Invalid",
"SaveContactMethod":"LastName Invalid",
"SaveContactMethod":"MiddleName Invalid"
【问题讨论】:
也许您需要与您的客户交谈并向他们解释这是一个愚蠢的要求,可能会在未来引入各种问题? 是的,从技术上讲,这是有效的 JSON,但是,根据规范,它的 含义 是忽略前面的重复键。因此,您的在线工具中的警告。如果您关心数据的完整性,则 JSON 无效。由于您确实关心完整性,因此您不能再将其称为 JSON。它现在是您自己的自定义格式,恰好类似于 JSON 几天后,我们将看到来自这家公司的另一位开发人员的问题:“如何解析带有重复键的 JSON?我需要所有值,但只需要我的库返回最后一个。” 哦,好吧... @B.Balamanigandan:我说的是可怜的家伙,他必须解析你正在创建的输出,而不是你。 :-) 任何时候你发现自己说“我需要一个重复的密钥”,我认为是时候重新考虑你的设计了。 【参考方案1】:不,这是不可能的。
这将是无效的* JSON:
"error" :
"SaveContactMethod":"FirstName Invalid",
"SaveContactMethod":"LastName Invalid",
"SaveContactMethod":"MiddleName Invalid"
你可以查看这个here:
Warning:Duplicate key, names should be unique.[Code 23, Structure 9]
Warning:Duplicate key, names should be unique.[Code 23, Structure 13]
*Depending on what you call valid
如果你真的想走这条路,根据 RFC 4627,你可以使用 StringBuilder
类。
既然你似乎不明白,那么取决于你所说的有效是什么意思。
ECMA-262:
在对象内有重复名称字符串的情况下, 同一个键的词法前面的值将被覆盖。
这意味着:如果你得到三个SaveContactMethod
,你只需要在 ECMA 脚本 (JS) 中的"MiddleName Invalid"
。使用 c# 序列化,这甚至是不可能的。您需要为它编写自己的 JsonSerializer。
【讨论】:
只是为了扩展这一点,重要的是要记住 JSON 代表一个 对象。您无法在我知道的任何其他 OO 概念中创建具有重复属性名称的对象。当然它会编译没有错误(尽管有警告),但它实际上不会可用。 我假设这里的 VALID 意味着只有 json 字符串的语法是有效的,说打开和关闭是正确的......等等 @Luminous_Dev 真正让我好奇的是,API 究竟是如何使用带有重复键的 JSON 来制作可用的东西... 您的要求毫无意义,只要您需要以编程方式使用 JSON @B.Balamanigandan。你真的应该使用一个简单的 errorMessage 字段,它是一个错误消息数组。这就是xy 的问题。 @B.Balamanigandan,这个要求是不可能的。如果您需要有关 StringBuilder 的帮助,请阅读文档。但这不是你应该这样做的方式,我不会为你写它。这将是一种广泛的方式。通过与给您要求的人交谈来更改要求。与此人沟通为什么这是一个不好的要求。在此处参考您的问题。但这就是我本次讨论的一部分。对于那个很抱歉。我也有我的项目需要完成。也许其他人编写了适合您需求的解决方案。请随意对我的回答投反对票。【参考方案2】:你有一个经典的“XY”问题。您已经问过“我该如何做 X”,但您真的需要做 Y,并且您认为 X 是到达 Y 的唯一途径 - 但 X 要么不可能,要么非常困难。通过稍微改变您的要求,您可以以不同的方式到达 Y,但您还没有看到这一点,因为您被困在 X 上。
这是您的 X:您想要获取的 JSON 格式:
"error" :
"SaveContactMethod":"FirstName Invalid",
"SaveContactMethod":"LastName Invalid",
"SaveContactMethod":"MiddleName Invalid"
正如其他人所说,这将丢弃所有错误消息,但在将其加载到 C# 代码中时除外。
但是,有一种非常简单的方法可以获取所有错误消息。您只需将您期望的 JSON 改为 this 即可:
"error" :
"SaveContactMethod": [
"FirstName Invalid",
"LastName Invalid",
"MiddleName Invalid"
]
如果您只有一条错误消息,您应该仍然使用列表:
"error" :
"SaveContactMethod": [
"FirstName Invalid"
]
这样,当您将 JSON 加载到您的 C# 代码中时,它总是具有相同的类型,Dictionary<string,List<string>>
,无论是一个错误还是多个错误。
这就是你的 XY 问题中的 Y。与其把头撞在“我想在 JSON 中有重复的键”的墙上,不如想办法绕过墙:有一个带有值列表的键。现在您可以做您真正需要的事情,即从表单中获取所有错误消息,每条错误消息只需一个键名。
【讨论】:
这对我的生活总体有帮助以上是关于使用 C# 返回具有重复键的 Json 对象的主要内容,如果未能解决你的问题,请参考以下文章