You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure APIM策略问题:从SOAP请求提取用户名并设置变量

提取SOAP请求中的Username并设置变量的问题

问题背景

我的API收到如下SOAP请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://example.com/webservice">
   <soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
         <wsse:UsernameToken>
            <wsse:Username>myUsername</wsse:Username>
            <wsse:Password>myPassword</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <web:YourRequest>
      </web:YourRequest>
   </soapenv:Body>
</soapenv:Envelope>

需求是提取请求中的Username字段,将其设置为变量。

尝试的方案及错误

我先尝试将入站请求转换为JSON:

<xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="true" />

然后设置变量:

<set-variable name="jsonBody" value="@(context.Response.Body.As<JObject>(preserveContent: true))"/>
<set-variable name="age" value="@((string)((JObject)context.Variables[" jsonBody"])["soapenv$Envelope"]["soapenv$Header"]["wsse$Security"]["wsse$UsernameToken"]["wsse$Username"]["$t"])"/>

但出现了以下错误:

set-variable (0.243 ms)
{
    "messages": [
        {
            "message": "Expression evaluation failed.",
            "expression": "context.Response.Body.As<JObject>(preserveContent: true)",
            "details": "Object reference not set to an instance of an object."
        },
        "Expression evaluation failed. Object reference not set to an instance of an object.",
        "Object reference not set to an instance of an object."
    ]
}

我并非一定要将请求转换为JSON,只是更熟悉JSON处理方式,希望能修正该策略或提供更合适的方案。

修正方案

方案一:修正JSON转换的错误

错误核心原因有两个:

  1. 错误引用了context.Response.Body,入站请求应使用context.Request.Body
  2. 变量名" jsonBody"包含多余空格,导致无法正确读取变量

修正后的配置如下:

<!-- 将XML转换为JSON -->
<xml-to-json kind="javascript-friendly" apply="always" consider-accept-header="false" />

<!-- 读取转换后的JSON到变量 -->
<set-variable name="jsonBody" value="@(context.Request.Body.As<JObject>(preserveContent: true))" />

<!-- 提取Username到变量 -->
<set-variable name="username" value="@((string)((JObject)context.Variables["jsonBody"])["soapenv$Envelope"]["soapenv$Header"]["wsse$Security"]["wsse$UsernameToken"]["wsse$Username"]["$t"])" />

方案二:直接用XPath提取XML(更高效)

不需要转换JSON,直接通过XPath定位XML中的Username元素,步骤更简洁高效:

<set-variable name="username" value="@(context.Request.Body.AsXPathSelectElement("//wsse:Username", new XmlNamespaceManager(new NameTable()) { { "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" } }).Value)" />

也可以使用extract-variable策略实现:

<extract-variable name="username">
  <xpath expression="//wsse:Username" namespace-map="@{ new Dictionary<string, string> { { "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" } } }" />
</extract-variable>

内容的提问来源于stack exchange,提问作者Victor Mason

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:53:12