【问题标题】:How to store JSON Payload using Azure API Manager cache-store-value policy?如何使用 Azure API Manager 缓存存储值策略存储 JSON 负载?
【发布时间】:2019-07-02 04:20:20
【问题描述】:

美好的一天,

我正在尝试使用“缓存存储值”策略将传入的 JSON 有效负载存储到 Azure API 管理器内部缓存中。密钥将是有效载荷内的字段之一。我能够提取密钥,但是当我尝试存储有效负载时出现错误

“表达式评估失败。对象引用未设置为对象的实例。”

这是我正在编写的代码

<policies>
<inbound>
    <base />
    <set-variable name="processIdKey" value="@((string)context.Request.Body.As<JObject>()["id"])" />
    <set-variable name="validationResults" value="@(context.Request.Body.As<JObject>())" />
    <cache-store-value key="@((string)context.Variables["processIdKey"])" value="@((string)context.Variables["validationResults"])" duration="30" />
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>

我稍后需要在 api 的另一种方法中提取值,因此需要知道如何将 JSON 有效负载存储在缓存中并提取相同的值以在另一种方法中作为响应发送。

提前感谢您的帮助。

【问题讨论】:

  • 从 Azure 门户进行测试调用并检查跟踪以查看哪个表达式准确产生了空引用。在不知道您请求的详细信息的情况下,我会说您需要检查 Body 是否为空(它用于 GET/HEAD 请求)。
  • 问候 Vitaliy,对不起,我应该把跟踪错误。我在以下语句中遇到错误 现在我找到了解决方案。原因是上下文变量 Request 不能被多次引用。所以我必须将它存储在一个变量中,然后将其转换为字符串。
  • 啊。其背后的原因是 APIM 默认不缓存请求体。当您在策略 (.As()) 中读取它时,正文被消耗并替换为 null 以不将其存储在内存中两次(一次作为解析的 JObject,第二次作为流)。如果您总是需要它作为 JObject 将它放入变量中是正确的方法。但是,如果您需要对其进行两次解析,您可以通过调用 .As(preserveContent: true) 来实现。这样的调用仍然会为您提供 JObject,但也会缓存原始主体以供进一步使用。
  • 问候 Vitaliy,太好了,解释真的很有帮助。你是* :-)
  • 我希望在文档中明确说明对尸体的处置!感谢您的提问和回答!

标签: azure-api-management


【解决方案1】:

我找到了答案,问题是,我们不能在整个代理中多次提取 context.Request 对象。所以我要做的就是将它作为 JObject 存储在一个变量中,然后从中提取“id”字段。稍后将其转换为字符串以存储在缓存中。这是更新的代码。

<policies>
<inbound>
    <base />
    <set-variable name="validationResults" value="@(context.Request.Body.As<JObject>())" />
    <set-variable name="processIdKey" value="@((string)((JObject)context.Variables["validationResults"])["id"])" />
    <set-variable name="payload" value="@((string)((JObject)context.Variables["validationResults"]).ToString())" />
    <cache-store-value key="@((string)context.Variables["processIdKey"])" value="@((string)context.Variables["payload"])" duration="30" />
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>

希望对您有所帮助。谢谢。

【讨论】:

    【解决方案2】:

    试试context.Request.Body.As&lt;string&gt;()。方法 As 目前支持以下类型作为通用参数值:

    byte[]
    string
    JToken
    JObject
    JArray
    XNode
    XElement
    XDocument
    

    请注意,如果您尝试通过 不包含有效 JSON 的响应调用 .As&lt;JObject&gt;,您会收到异常,这同样适用于其他类型。

    这里是关于缓存的article,您可以参考。

    【讨论】:

    • 问候乔伊,如前所述,我发现解决方案将发布答案。感谢您的帮助。
    猜你喜欢
    • 2017-05-28
    • 2016-03-04
    • 1970-01-01
    • 2020-06-11
    • 2019-03-13
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    相关资源
    最近更新 更多