如何从 Azure API 管理中的请求正文获取原始日期时间值?
How to get raw datetime value from request body in Azure API Management?
目前我正在尝试访问 Azure API 管理中 JSON 属性 的原始值。
我有以下要求:
{
"date": "2019-12-09T12:00:00Z"
}
和类似的操作:
<inbound>
<base />
<!-- Assume datetime in format 2019-12-09T12:00:00Z -->
<set-variable name="time" value="@(context.Request.Body.As<JObject>()["date"])" />
<!-- Attempt to acquire raw value -->
<set-variable name="rawValue" value="@{
var value = JsonConvert.SerializeObject((JValue)context.Variables["date"]);
return value.ToString();
}" />
<!-- raw value is: \"2019-12-09T12:00:00Z\" -->
</inbound>
我在这里找到了类似的答案:
所以我尝试序列化对象。
但就我而言,Azure API Management 输出带有附加引号的原始值,如下所示:
set-variable (0 ms)
{
"message": "Context variable was successfully set.",
"name": "rawValue",
"value": "\"2019-12-09T12:00:01Z\""
}
一种简单的方法是替换它们,但是没有更好的解决方案吗?
+++更新+++
刚刚找到这个解决方案:
Convert.ToDateTime(context.Request.Body.As<JObject>()["date"]).ToString("o")
输出:
set-variable (0 ms)
{
"message": "Expression was successfully evaluated.",
"expression": "Convert.ToDateTime(context.Request.Body.As<JObject>()[\"date\"]).ToString(\"o\")",
"value": "2019-12-10T09:10:00.0000000Z"
}
IMO 这仍然不是我预期的 100%,但至少它是正确的格式。
我仍然愿意寻求更好的解决方案。
你在这里完全混淆了类型。 context.Request.Body.As<JObject>()["date"]
returns 包含字符串值 2019-12-09T12:00:00Z
的 JToken。当您调用 JsonConvert.SerializeObject((JValue)context.Variables["date"])
时,您要求 JSON.NET 将给定的标记序列化为一个字符串。字符串在 JSON 中表示为带引号的一系列字符,因此 value
当然等于 "2019-12-09T12:00:01Z"
,即内部带有 "
的字符串。如果您只想要字符串值,请执行:
<set-variable name="rawValue" value="@(context.Request.Body.As<JObject>()["date"].ToString())" />
随着即将发布的 Azure API 管理版本的宣布 here,应该可以指定他自己的 JsonSerializerSettings 并且可以像这样存储变量:
<set-variable name="body" value="@(context.Request.Body.AsJObject(preserveContent = true, new JsonSerializerSettings() { DateParseHandling = DateParseHandling.None } ))" />
我会 post 部署后立即更新,我可以设法对其进行测试。
更新
结合使用新的 context.Request.Body.AsJObject()
方法和 JsonSerializer
设置,DateTime 值的输出现在不会再更改:
{
"source": "set-variable",
"timestamp": "2020-11-19T07:33:34.7901180Z",
"elapsed": "00:00:00.0018103",
"data": {
"message": "Context variable was successfully set.",
"name": "timestampFilter",
"value": "2019-12-09T12:00:00Z"
}
}
目前我正在尝试访问 Azure API 管理中 JSON 属性 的原始值。 我有以下要求:
{
"date": "2019-12-09T12:00:00Z"
}
和类似的操作:
<inbound>
<base />
<!-- Assume datetime in format 2019-12-09T12:00:00Z -->
<set-variable name="time" value="@(context.Request.Body.As<JObject>()["date"])" />
<!-- Attempt to acquire raw value -->
<set-variable name="rawValue" value="@{
var value = JsonConvert.SerializeObject((JValue)context.Variables["date"]);
return value.ToString();
}" />
<!-- raw value is: \"2019-12-09T12:00:00Z\" -->
</inbound>
我在这里找到了类似的答案:
但就我而言,Azure API Management 输出带有附加引号的原始值,如下所示:
set-variable (0 ms)
{
"message": "Context variable was successfully set.",
"name": "rawValue",
"value": "\"2019-12-09T12:00:01Z\""
}
一种简单的方法是替换它们,但是没有更好的解决方案吗?
+++更新+++
刚刚找到这个解决方案:
Convert.ToDateTime(context.Request.Body.As<JObject>()["date"]).ToString("o")
输出:
set-variable (0 ms)
{
"message": "Expression was successfully evaluated.",
"expression": "Convert.ToDateTime(context.Request.Body.As<JObject>()[\"date\"]).ToString(\"o\")",
"value": "2019-12-10T09:10:00.0000000Z"
}
IMO 这仍然不是我预期的 100%,但至少它是正确的格式。 我仍然愿意寻求更好的解决方案。
你在这里完全混淆了类型。 context.Request.Body.As<JObject>()["date"]
returns 包含字符串值 2019-12-09T12:00:00Z
的 JToken。当您调用 JsonConvert.SerializeObject((JValue)context.Variables["date"])
时,您要求 JSON.NET 将给定的标记序列化为一个字符串。字符串在 JSON 中表示为带引号的一系列字符,因此 value
当然等于 "2019-12-09T12:00:01Z"
,即内部带有 "
的字符串。如果您只想要字符串值,请执行:
<set-variable name="rawValue" value="@(context.Request.Body.As<JObject>()["date"].ToString())" />
随着即将发布的 Azure API 管理版本的宣布 here,应该可以指定他自己的 JsonSerializerSettings 并且可以像这样存储变量:
<set-variable name="body" value="@(context.Request.Body.AsJObject(preserveContent = true, new JsonSerializerSettings() { DateParseHandling = DateParseHandling.None } ))" />
我会 post 部署后立即更新,我可以设法对其进行测试。
更新
结合使用新的 context.Request.Body.AsJObject()
方法和 JsonSerializer
设置,DateTime 值的输出现在不会再更改:
{
"source": "set-variable",
"timestamp": "2020-11-19T07:33:34.7901180Z",
"elapsed": "00:00:00.0018103",
"data": {
"message": "Context variable was successfully set.",
"name": "timestampFilter",
"value": "2019-12-09T12:00:00Z"
}
}