为啥 Set-Body 策略无法识别我的 POST 正文?

Posted

技术标签:

【中文标题】为啥 Set-Body 策略无法识别我的 POST 正文?【英文标题】:Why does Set-Body policy not recognize my POST body?为什么 Set-Body 策略无法识别我的 POST 正文? 【发布时间】:2019-03-28 13:51:45 【问题描述】:

我正在尝试将 Azure(api 管理)中的 API 端点连接到后端服务。但是,set-body 策略无法识别我的 JSON 主体,因此不会将其转换为后端调用。

我已经尝试了所有我能想到的“液体”和“无”模板的迭代。微软文档是无用的,因为即使“液体”模板在文档中也是大写的,而它需要小写。即使是每个人都指出的 Deep Dive 文章也是误导和/或过时的。

我曾经能够使用液体模板获得 context.Request.OriginalUrl 引用来工作,但我似乎无法获得 body.json 引用来工作

这是我在该部分中的政策(纯粹是为了测试 - 这对我正在做的事情没有用):

<set-body template="liquid">
    Calling User Agent: context.Request.OriginalUrl
</set-body>

这是我必须尝试读取 json 正文的示例(通过 POST 传递):

<set-body template="liquid">body</set-body>

我已经尝试了几次迭代和输入,如下所示:

<set-body template="liquid">body.json</set-body>

通过这样的身体时:

"json":"this is an example body"

不管我做什么,这是我在测试调用后在跟踪中看到的:

set-body (0.069 ms)

    "input": null,
    "output": ""
 

我显然愿意使用“无”模板,但我遇到了同样的问题。文档有误 - 如果我复制/粘贴示例:

<set-body>@(context.Body.As<String>())</set-body>

我收到如下错误:

One or more fields contain incorrect values:
Error in element 'set-body' on line 32, column 10: 'IProxyRequestContext' does not contain a definition for 'Body' and no extension method 'Body' accepting a first argument of type 'IProxyRequestContext' could be found (are you missing a using directive or an assembly reference?)

当我没有出错时,它返回相同的“输出”:“”输出。

【问题讨论】:

【参考方案1】:

为了能够将正文作为液体模板中的对象访问,您必须将Content-Type 标头设置为application/json,如docs 中所述。 如果您的请求已经在发送此标头,那么它应该可以在不设置它的情况下工作。

inbound 部分中的此类政策将保证其按预期工作

<set-header name="Content-Type" exists-action="override">
    <value>application/json</value>
</set-header>
<set-body template="liquid">body.json"</set-body>

至于通过context 变量访问它,您必须以context.Request.Body.As&lt;string&gt;() 访问它,如docs 中所述,所以像这样

<set-body>@(context.Request.Body.As<string>())</set-body>

set-body的官方参考好像没有你说的问题。 您指的是其他文档吗?如果它位于docs.microsoft.com,您可以在每个文档的末尾打开一个问题。

【讨论】:

我正在尝试使用 @(context.Request.Body.As()) 但它不适用于我自己。我不断收到 500 并且在跟踪中我看到一个错误。在设置正文之前,我还有其他一些策略“设置后端服务”、“登录到事件中心”,然后设置正文。这会产生影响吗? "source": "set-body", "timestamp": "2019-04-02T15:17:24.1314885Z", "elapsed": "00:00:00.0012055", "data" : "messages": [ "message": "表达式评估失败。", "expression": "context.Request.Body.As()", "details": "对象引用未设置为实例一个物体。” , "表达式评估失败。对象引用未设置为对象的实例。", "对象引用未设置为对象的实例。" ] 您是否尝试在其他策略中访问context.Request.Body?如果是这样,请确保使用 preserveContent 参数为 true - context.Request.Body.As&lt;string&gt;(preserveContent: true)。这也记录在同一个官方文档中。 谢谢普拉莫德瓦拉瓦拉。内容类型似乎有效,尽管文档中不清楚何时设置它。我不得不在“深度潜水”文章中找到它,即便如此,它还是在顶部。我现在遇到的一个问题是,当我在 策略中发送任何“特殊字符”时,它会出错。我正在尝试通过一个简单的 json 对象,该对象包含一个带参数的 URL。set-body 不喜欢“=”、“&”或“^”字符,但它们是必要的......关于如何的任何想法要通过吗? 该错误有点误导问题似乎是因为&amp; 是XML 中的转义字符。由于您需要它是有效的 URL,请将其替换为 %26

以上是关于为啥 Set-Body 策略无法识别我的 POST 正文?的主要内容,如果未能解决你的问题,请参考以下文章

需要使用 Azure APIM set-body 策略修改响应

为啥WPF无法识别我的这个DynamicResource

为啥 Javascript 无法识别我的构造函数?

为啥我的程序无法识别我的方法?

为啥 Xcode 无法识别我的核心数据实体的属性

为啥编译器无法识别我的 return 语句?