如果请求包含Accept=application/xml,我将尝试将json响应转换为xml。否则,应返回json响应。
这是我的政策:
<policies>
<inbound><base /></inbound>
<backend><base /></backend>
<outbound>
<base />
<json-to-xml apply="content-type-json" consider-accept-header="true" />
</outbound>
<on-error><base /></on-error>
</policies>
当我在没有Accept头的情况下测试它时,一切都很好(200 OK,json正确返回)。
然而,添加accept标头后,我得到了406"不可接受"。
经过编辑的跟踪(添加标题Ocp-Apim trace:true后)可在https://gist.github.com/jhgbrt/9df92cb0a140804ea01c.在该轨迹中,您将看到以下内容:
- 在"inbound"部分中,确认存在值为"application/xml"的请求标头"Accept"。
request-executor
块包含一条消息,上面写着"请求正在转发到后端服务。" - 在"outbound"块中,您已经看到406不可接受,Accept头被删除,之后json到xml块因此失败
我错过了什么?
我怀疑问题在于您的后端API不支持返回application/xml
,并选择返回406,而不是忽略接受头,只返回JSON。
解决此问题的一种方法可能是(我也会尝试)使用<set-variable>
将accept标头存储在变量中,使用<set-header>
策略从入站请求中删除accept标头,然后在出站请求上,使用<choose>
策略检查变量,并且仅在accept标头为application/xml
时应用转换
这个策略应该有效,尽管我必须承认我在转换JSON时遇到了一些问题。
<policies>
<inbound>
<choose>
<!-- Check for application/xml in the Accept Header -->
<when condition='@(context.Request.Headers.GetValueOrDefault("Accept","").Contains("application/xml"))'>
<!-- Update the accept header to ask for JSON -->
<set-header name="Accept" exists-action="override">
<value>application/json</value>
</set-header>
<!-- Create flag to record that we switched accept header -->
<set-variable name="ToXml" value="True" />
</when>
<otherwise>
<set-variable name="ToXml" value="False" />
</otherwise>
</choose>
<base/>
</inbound>
<backend>
<base/>
</backend>
<outbound>
<base/>
<choose>
<!-- If we switched the accept header, then apply conversion -->
<when condition='@((string)context.Variables["ToXml"] == "True")'>
<json-to-xml apply="always" consider-accept-header="false" />
</when>
</choose>
</outbound>
</policies>