【问题标题】:Sending JSON with escape characters such as group separators发送带有转义字符(例如组分隔符)的 JSON
【发布时间】:2016-11-05 16:15:21
【问题描述】:

具体问题:JSON中的组分隔符(0x1D)等字符应该如何格式化?

详情: 我继承了一个 C# 代码库,它正在读取一些条形码,将它们放入 JSON 消息中并将它们发送到服务(不一定是基于 C# 或 Windows!)

代码采用字节数组如:

byte[] rawData = { 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 
                   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 52, 29, 49,
                   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48};

并使用这样的代码将此字节数组转换为放入 .json 中的字符串:

string dataNew = Regex.Unescape(new string(Encoding.ASCII.GetString(rawData).ToCharArray()));

.json 的相关部分如下所示:

"Notes": [
  {
    "Id": 0,
    "Details": "Produc code: CodeType: DataMatrix, Data: 000000000000000000000000000004\u001d1000000000000000",
    "Active": true,
    "Acknowledged": false,
    "Reported": false
  }
],

如您所见,Encoding.ASCII.GetString... 处理 ASCII 字符 29 (0x1d) 略有不同。它输入了一个“\u001”。如果您不输入 Regex.Unescape,它会输入“\\u001”。我对编码和 .json 感到不安。谁能告诉我:

  1. 什么是“\u001”。是 Microsoft 特有的吗?
  2. 收到此消息的人们表示他们的服务器“阻塞”了此消息。没有组分隔符时没有问题。可以通过 .json 消息发送组分隔符吗?如果是这样怎么办?如果可行,您将如何使用 C# 技术对其进行解码?

更多信息:服务器人员说 \u001 最终呈现为 ^] (表示不可打印的字符)。我可以在发送消息之前去掉 \u001,这可能不是一个坏主意。但我突然想到还有其他不可打印的字符(例如 CR、LF),最好保留该信息并通过 .json 发送。

请原谅我的含糊不清。我仍然熟悉这个代码库和这些特殊的想法。我确实尝试找出 \u001 是什么,但无济于事。我可以要求比“窒息”更好的解释,但如果能想到一些具体问题就好了。如果我可以提供澄清或更多详细信息,请告诉我。

【问题讨论】:

  • 什么是rawData?它是可以具有任何值的任意字节序列吗?还是它们实际上是 ASCII 字符值?
  • 据我所知,它们是仅代表 ascii 字符值的字节。也就是说,我不相信我们需要处理 0-127 之外的任何字符。我“清理”了数组,使其大部分为 0(ascii 48)。

标签: c# json json.net escaping ascii


【解决方案1】:

插入\u 转义序列的不是Encording.ASCII.GetString;正在执行此操作的是 JSON 序列化过程(您未在问题中显示),这是完全正常和预期的。

JSON 中,字符串中的不可打印字符被编码为\u + 四个十六进制数字,其中数字是字符的Unicode (UTF-16) 表示。在您的输出中,您可以看到实际发生的情况:您有 \u001d,它是原始字节序列中的 ASCII 字符 29。

通常,为避免创建和解码 JSON 时出现问题,您应该始终使用 JSON 序列化库,例如 JSON.Net,它旨在为您处理所有这些问题。我猜您在问题中提到的“服务器人员”正在尝试手动解析 JSON,这就是他们遇到麻烦的原因。如果你做的一切都正确,你根本不需要使用正则表达式来操作 JSON 字符串,包括使用Regex.Unescape

这里有一个简短的演示:https://dotnetfiddle.net/Uy3PcM

【讨论】:

  • 感谢布赖恩的回复。我认为 \u001d 存在于 .json 序列化之前,您可以从将鼠标悬停在断点处看到。我同意如果您将字符串写入行,它不会显示。也许这有什么线索?无论如何,你给了我很多思考。 \u001d 是通用的(或 Microsoft 特定的)。如果一般,服务器人员是否使用库?我将在周一确认,但相信他们可能正在使用 Ruby on Rails。我假设有 .json 库可用于处理 \u001d 的 Ruby,但不确定。
  • 非常感谢您让我了解 dotnetfiddle。非常令人印象深刻。不幸的是,据我所知,您不能将鼠标悬停在断点处的值(甚至有断点?)。但仍然非常有用。
  • \u001d0x1D 相同——它是用四个十六进制数字而不是两个数字编码的组分隔符。它根本不是“微软特有的”;它是standard ASCII 编码为standard JSON。所有值得一提的 JSON 库都应该能够处理 \u 字符转义符号,无论是什么语言,如果它们遵循标准。是的,有几个可用于 Ruby 的 JSON 库,如JSON.org 页面底部所示。
  • DotNetFiddle 不支持断点或调试是正确的;这就是为什么我使用 Console.WriteLine 来显示所有内容的值。如果您想在调试器中单步执行该代码,只需将其转储到 Visual Studio 中的新控制台应用程序项目中即可。不过,您需要包含对 JSON.Net 的引用。
  • 非常感谢布赖恩。标记为答案。我想我正在解决这个问题。我发布了一个新问题:stackoverflow.com/questions/40477952/… 如您所见,我丢失了单个字符 \u 0 0 1 d,当我反序列化 json 字符串时,它被替换为 29。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多