Azure API管理:带有consider-accept-header的json-to-xml策略



如果请求包含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>

最新更新