【问题标题】:Ordering fields in .NET web service response.NET Web 服务响应中的排序字段
【发布时间】:2015-01-26 17:50:26
【问题描述】:

我正在从移动应用程序调用 .NET Web 服务(我认为是 WCF,我不是 .NET 专家)以获取 JSON 响应,并且我想重新排序这些字段。是的,我知道 JSON 的规范(在某种程度上有这样的事情)说它不支持排序。我只是想找到一种方法来从 Web 服务中订购响应字符串,然后再更新客户端应用程序以在之后对数据进行排序。

我发现了这个:https://msdn.microsoft.com/en-us/library/ms729813.aspx

但是在每个字段上使用[DataMember(Order = 0)](当然具有不同的排序值)对响应中字段的顺序没有影响。此属性是否仅适用于 XML 响应?

【问题讨论】:

  • 我很好奇根据 JSON 属性的顺序开发了什么样的脆弱、不可更新的解决方案。我的意思是,如果它被解析成一个对象,那么“订单”这个词背后甚至没有任何意义。该解决方案是否直接使用 JSON 字符串?
  • @nasch - 即使您使用 Swift 或其他语言,关键问题是应用程序是否甚至注意属性的顺序。如果正在进行任何类型的反序列化,那么您就是在浪费精力在服务器响应中重新排序它们。按字母顺序排列的属性列表是所有反射库的工作方式。我以前从未见过应用程序手动处理 JSON 字符串,这就是我问的原因。我强烈建议您在此问题上浪费更多时间之前检查应用逻辑
  • @nasch 但您是否检查过实际响应,或者客户所说的响应?客户端可能正在反序列化结果并按字母顺序输出(即使服务的顺序不同),这就是我问的原因
  • @JDB,我想我知道你在说什么,我正在咨询 iOS 开发者。
  • @JDB 我认为您的评论是关键。我们已经确定不更新客户端应用程序就没有可行的解决方案。如果您想改写为答案,我会接受,并感谢大家的帮助。

标签: c# .net json


【解决方案1】:

JSON 属性的顺序通常无关紧要,因为 JSON 几乎总是反序列化为对象。一旦发生这种情况,属性的原始“顺序”就变得毫无意义。

例如,考虑以下代码:

const data = JSON.parse('{ "a": "Aquaman", "b": "Batman", "c": "Catwoman" }');
// data.a == "Aquaman"
// data.b == "Batman"
// data.c == "Catwoman"

更改这些属性的顺序不会对反序列化的对象产生影响。大多数面向对象的语言,包括 JavaScript、Java 和 C#,都没有内置的属性“顺序”概念。

const data = JSON.parse('{ "c": "Catwoman", "b": "Batman", "a": "Aquaman" }');
// data.a == "Aquaman"
// data.b == "Batman"
// data.c == "Catwoman"

如果您的客户端应用程序在输出 CSV 文件之前对 JSON 进行反序列化,则 JSON 属性的顺序将不会影响 CSV 字段的顺序。

更改 CSV 字段的顺序需要更新应用程序。

可以编写自己的 JSON 序列化程序以确保属性的顺序符合要求,然后编写自己的 JSON 解析器将 JSON 字符串直接转换为 CSV,从而保留这些字段的顺序.将 JSON 反序列化为对象会破坏字段顺序信息,因此您必须直接从原始 JSON 字符串转为 CSV。

或者您可以更改 JSON 的格式以使用确实保留元素顺序的数组等。比如:

const data = JSON.parse('{ "c": "Catwoman", "b": "Batman", "a": "Aquaman", "__fieldMeta": { "order": [ "c", "b", "a" ] } }');
// data.__fieldMeta.order[0] == "c"
// data.__fieldMeta.order[1] == "b"
// data.__fieldMeta.order[2] == "a"

或者,您可以切换到保留元素顺序的序列化格式,例如 XML。

<data c="Catwoman" b="Batman" a="Aquaman" />
const dom = (new DOMParser()).parseFromString(
  `<data c="Catwoman" b="Batman" a="Aquaman" />`, "application/xml");
// dom.firstElementChild.attributes[0].localName == "c"
// dom.firstElementChild.attributes[1].localName == "b"
// dom.firstElementChild.attributes[2].localName == "a"

很遗憾,所有这些选项都需要更新客户端应用程序。我认为没有办法解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多