Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在Azure API管理策略中重用响应上下文变量?_C#_Azure Api Management_Api Management_Apim - Fatal编程技术网

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

C# 如何在Azure API管理策略中重用响应上下文变量?,c#,azure-api-management,api-management,apim,C#,Azure Api Management,Api Management,Apim,我正在使用Azure API管理解决方案撰写一份概念证明 我正在尝试编写一个策略,该策略执行以下操作: 使用向API的身份验证端点发出请求 身份验证API返回两个密钥,它们必须作为http头包含,以便能够向其他端点发出后续请求 我正在使用JObject 然后我尝试从json对象的两个属性(它们是字符串)中读取值 然后,我将向不同的API端点发出后续请求,并设置两个http头。头的值必须是来自第一个(身份验证)响应的两个变量 这就是我目前的政策: <inbound> <b

我正在使用Azure API管理解决方案撰写一份概念证明

我正在尝试编写一个
策略,该策略执行以下操作:

  • 使用
    向API的身份验证端点发出请求
  • 身份验证API返回两个密钥,它们必须作为http头包含,以便能够向其他端点发出后续请求
  • 我正在使用
    JObject
  • 然后我尝试从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>

https://www.service.com/api/authenticate
邮递
应用程序/json
@{
var-credentials=newjobject();
添加(新的JProperty(“logonId”,“API_LOGON_USERNAME}”);
添加(新的JProperty(“logonPassword”,“{{API_LOGON_PASSWORD}”);
返回凭据。ToString();
}
https://www.service.com/api/data
得到
@{
JObject标识=((IResponse)context.Variables[“auth”]).Body.As();
返回identity.SelectToken(“TokenA”).ToString();
}
@{ 
JObject标识=((IResponse)context.Variables[“auth”]).Body.As();
return identity.SelectToken(“TokenB”).ToString();
}
应用程序/json
@{ 
JObject api_response=((IResponse)context.Variables[“data”]).Body.As();
返回api_response.ToString();
}
我遇到的问题是设置第二个标头(令牌B)的值。似乎无法重复使用上下文变量
(IResponse)context.Variables[“auth”]

当我查看跟踪时,我看到第一个
策略的以下输出:

“消息”:“表达式已成功计算。”, “值”:“XXXXXXXXXXXXXXXXXX”

但是对于第二个
策略,我得到:

“消息”:“表达式计算失败。”, “详细信息”:“对象引用未设置为对象的实例。”

我可以看到,在对第一个策略调用该方法后,我不再能够在第二个
策略中以相同的方式重用上下文变量

我试过:

  • 使用
    设置令牌字符串。我相信
    可以返回的类型数量有限,而且我无法返回
    I响应
    JObject
    。如果我尝试转换为json,然后提取每个属性(TokenA和TokenB)的字符串,我会遇到与上面相同的问题
有人能帮我复制
I响应
对象或
JObject
对象的语法吗?这样我就可以使用
.SelectToken()
读两遍了?我肯定我误解了一个基本概念,但我远不是一个经验丰富的C#开发者


谢谢

您收到错误的原因是您读取响应正文的方式。当你把身体读作

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

执行此操作时,将保留原始主体,并且在计算中仅注入主体的副本。 您可以在以下站点找到关于此的深入文档:

出现错误的原因是您读取响应正文的方式。当你把身体读作

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

执行此操作时,将保留原始主体,并且在计算中仅注入主体的副本。 您可以在以下站点找到关于此的深入文档:

完美答案。谢谢你,曼达。不确定我是如何在docs中漏掉它的。JObject应该作为变量的值来支持。所以,您应该能够这样做,并在以后改用tokens变量。这样做的好处是你只需要解析一次身体。完美的答案。谢谢你,曼达。不确定我是如何在docs中漏掉它的。JObject应该作为变量的值来支持。所以,您应该能够这样做,并在以后改用tokens变量。这样做的好处是您只需解析一次主体。