Azure APIM入站策略:用Set-Body在XML根节点追加AccessRequest元素
解决APIM中合并UPS API请求体的Set-Body策略错误
问题背景
UPS API要求请求体必须包含AccessRequest凭证元素,需通过Azure API Management(APIM)入站策略,将存储在Azure Key Vault的完整AccessRequest内容(可通过{{AccessRequest}}注入)与原请求体的TrackRequest内容合并。期望最终发送到UPS API的请求体示例如下:
<AccessRequest> <AccessLicenseNumber>xxxxxxxxxxxxx</AccessLicenseNumber> <UserId>xxxxxxxxxxxxx</UserId> <Password>xxxxxxxxxxxxx</Password> </AccessRequest> <TrackRequest> <Request> <TransactionReference> <CustomerContext>Your Test Case Summary Description</CustomerContext> </TransactionReference> <RequestAction>Track</RequestAction> <RequestOption>activity</RequestOption> </Request> <TrackingNumber>1Z6xxxxxxxxxxxxx</TrackingNumber> </TrackRequest>
原代码错误分析
你提供的Set-Body策略存在两处核心问题:
- 错误使用
JObject处理XML请求体:JObject是Newtonsoft.Json库中用于JSON对象的类型,完全不适合处理XML格式的请求体。 - 错误调用
Append方法与非法字段设置:JObject没有Append方法,且你试图拼接的是XML字符串而非JSON结构;同时错误地将Content-Type字段添加到请求体中,该字段属于请求头范畴,不应放在请求体内。
原错误代码:
<set-body>@{ var requestBody = context.Request.Body.As<JObject>(preserveContent: true); requestBody ["Content-Type"] = "application/xml"; requestBody.Append("{{AccessRequest}}"); return requestBody.ToString(); }</set-body>
正确的策略实现
1. 修正后的Set-Body策略
由于请求体是XML格式,直接以字符串形式读取原请求体并与AccessRequest拼接即可:
<set-body>@{ // 读取原请求体的XML字符串,preserveContent: true确保后续流程可重复读取请求体 var originalBody = context.Request.Body.As<string>(preserveContent: true); // 拼接AccessRequest和原请求体内容 return $"{Environment.GetEnvironmentVariable("AccessRequest")}{originalBody}"; }</set-body>
注:APIM中也可以直接使用
{{AccessRequest}}替代Environment.GetEnvironmentVariable("AccessRequest"),两种方式均能从Key Vault注入目标内容。
2. 补充设置Content-Type请求头
需要单独添加set-header策略确保请求头格式正确:
<set-header name="Content-Type" exists-action="override"> <value>application/xml</value> </set-header>
关键说明
- 直接以字符串处理XML请求体是最直接的方案,避免了XML解析/序列化的额外开销。
preserveContent: true参数必须设置,否则原请求体内容会被一次性消耗,后续策略无法读取。
内容的提问来源于stack exchange,提问作者Oisín Tarrant
相关产品推荐
相关产品推荐

