如何重用Azure API管理策略中的响应上下文变量?

问题描述 投票:0回答:1

我正在使用Azure API管理解决方案编写概念证明。

我正在尝试编写执行以下操作的<inbound>策略:

  • 使用<send-request>向API的身份验证端点发出请求。
  • 认证API返回两个密钥,必须将它们包含为http头,以便能够向其他端点发出后续请求。
  • 我正在使用JObject将来自身份验证API的响应解析为json,>
  • 然后,我试图从json对象的两个属性(它们是字符串)中读取值
  • 然后,我将向后续的API端点发出请求,并设置两个http标头。标头的值必须是来自第一个(身份验证)响应的两个变量。
  • 这是我目前的政策外观:

<inbound>
  <base />

  <!-- Authenticate with the API and get authentication tokens for subsequent calls -->
  <send-request mode="new" response-variable-name="auth" timeout="20" ignore-error="true">
    <set-url>https://www.service.com/api/authenticate</set-url>
    <set-method>POST</set-method>
    <set-header name="Content-Type" exists-action="override">
      <value>application/json</value>
    </set-header>
    <set-body>
      @{
        var credentials = new JObject(); 

        credentials.Add(new JProperty("logonId", "{{API_LOGON_USERNAME}}")); 
        credentials.Add(new JProperty("logonPassword", "{{API_LOGON_PASSWORD}}")); 

        return credentials.ToString(); 
      }
    </set-body>
  </send-request>

  <!-- Make second query to a different endpoint, using the authentication tokens as http headers -->
  <send-request mode="new" response-variable-name="data" timeout="20" ignore-error="true">
    <set-url>https://www.service.com/api/data</set-url>
    <set-method>GET</set-method>
    <set-header name="TokenA" exists-action="override">
      <value>
        @{
          JObject identity = ((IResponse)context.Variables["auth"]).Body.As<JObject>(); 
          return identity.SelectToken("TokenA").ToString(); 
        }
      </value>
    </set-header>
    <set-header name="TokenB" exists-action="override">
      <value>
        @{ 
          JObject identity = ((IResponse)context.Variables["auth"]).Body.As<JObject>(); 
          return identity.SelectToken("TokenB").ToString(); 
        }
      </value>
    </set-header>
  </send-request>

  <!-- Return response from the second API -->
  <return-response response-variable-name="responseData">
    <set-status code="200" reason="OK" />
    <set-header name="Content-Type" exists-action="override">
      <value>application/json</value>
    </set-header>
    <set-body>
      @{ 
        JObject api_response = ((IResponse)context.Variables["data"]).Body.As<JObject>(); 
        return api_response.ToString();   
      }
    </set-body>
  </return-response>
</inbound>

我遇到的问题是围绕设置第二个标头(令牌B)的值。看来我无法重用上下文变量(IResponse)context.Variables["auth"]

查看跟踪时,我看到第一个<set-header>策略的以下输出:

“ message”:“表达已成功评估。”,“ value”:“ xxxxxxxxxxxxxxxxxxxxx”

但是获得第二个<set-header>政策:

“消息”:“表达评估失败。”,“ details”:“对象引用未设置为对象的实例。”

我看到,在第一个策略上调用方法之后,我不再能够以第二个<set-header>策略中的相同方式重用上下文变量。

我尝试过:

  • 使用<set-variable>设置令牌字符串。我相信<set-variable>可以返回的类型数量有限,并且我无法返回IResponseJObject。如果我尝试转换为json,然后提取每个属性(TokenA和TokenB)的字符串,则会遇到与上述相同的问题。
  • [有人可以帮我提供语法,让我复制IResponse对象或JObject,以便我可以使用.SelectToken()对其进行两次读取吗?我敢肯定我误解了一个基本概念,但我与经验丰富的C#开发人员相去甚远!

谢谢

我正在使用Azure API管理解决方案编写概念证明。我正在尝试编写一个执行以下操作的策略:使用向...发出请求...

c# azure-api-management api-management apim
1个回答
0
投票

得到错误的原因是由于您读取响应正文的方式。当您将身体读为

JObject identity = ((IResponse)context.Variables["auth"]).Body.As<JObject>();

© www.soinside.com 2019 - 2024. All rights reserved.