我需要以某种不寻常的格式为客户输出一些 JSON。我的应用程序是用 Rails 5 编写的。
所需的 JSON:
{
"key": "\/Date(0000000000000)\/"
}
时间戳值需要在字符串的开头和结尾都有一个\/
。据我所知,这似乎是 .NET services 中常用的格式。 .我一直在尝试让斜线正确输出。
我将问题简化为具有单个 Controller 操作的普通 Rails 5 应用程序。到目前为止,我能想到的所有转义排列都失败了。
def index
render json: {
a: '\/Date(0000000000000)\/',
b: "\/Date(0000000000000)\/",
c: '\\/Date(0000000000000)\\/',
d: "\\/Date(0000000000000)\\/"
}
end
输出如下:
{
"a": "\\/Date(0000000000000)\\/",
"b": "/Date(0000000000000)/",
"c": "\\/Date(0000000000000)\\/",
"d": "\\/Date(0000000000000)\\/"
}
为了便于讨论,假设格式不能更改,因为它由第三方控制。
我已将测试应用程序上传到 Github 以演示该问题。 https://github.com/gregawoods/test_app_ignore_me
最佳答案
在与同事集思广益之后(感谢 @TheZanke),我们找到了一个适用于 native Rails JSON 输出的解决方案。
警告:此代码会覆盖 ActiveSupport 中的一些核心行为。使用风险自负,并应用明智的单元测试!
我们将其追溯到 ActiveSupport 中的 JSON 编码。所有字符串最终都通过 ActiveSupport::JSON.encode
进行编码。我们需要找到一种方法来短路该逻辑并简单地返回未编码的字符串。
首先我们扩展了EscapedString#to_json
方法找到here .
module EscapedStringExtension
def to_json(*)
if starts_with?('noencode:')
"\"#{self}\"".gsub('noencode:', '')
else
super
end
end
end
module ActiveSupport::JSON::Encoding
class JSONGemEncoder
class EscapedString
prepend EscapedStringExtension
end
end
end
然后在 Controller 中我们向 json 散列添加一个 noencode:
标志。这告诉我们的 to_json
版本不要进行任何额外的编码。
def index
render json: {
a: '\/Date(0000000000000)\/',
b: 'noencode:\/Date(0000000000000)\/',
}
end
呈现的输出显示 b
给了我们想要的,而 a
保留了标准行为。
$ curl http://localhost:3000/sales/index.json
{"a":"\\/Date(0000000000000)\\/","b":"\/Date(0000000000000)\/"}
关于ruby-on-rails - 如何在不转义反斜杠的情况下在 Rails 中输出 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44207331/