2015-11-23 74 views
1

如果請求包含Accept = application/xml,我試圖將json響應轉換爲xml。否則,應該返回json響應。Azure API管理:考慮接受頭的json-to-xml策略

這裏是我的政策:

<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> 

當我測試這個沒有接受頭,一切都很好(200 OK和JSON是正常返回)。

但是,添加accept頭,我得到了406不可接受。

可以在https://gist.github.com/jhgbrt/9df92cb0a140804ea01c處獲得跟蹤(在添加標題Ocp-Apim-Trace:true後)。在跟蹤中,您將看到以下內容:

  • 'inbound'部分確認請求標頭'Accept'的值爲'application/xml'。 request-executor塊包含一條消息,說明「請求正被轉發到後端服務」。
  • 在'outbound'塊中,您已經看到406不可接受,並刪除了Accept頭,之後json-to-xml塊因此失敗。

我錯過了什麼?

回答

2

我懷疑問題是你的後端API不支持返回application/xml,並選擇返回406而不是忽略accept頭,只是返回JSON。要解決這可能是(我也嘗試這個)

一種方式是存儲在使用<set-variable>一個變量接受頭,刪除使用<set-header>政策從入站請求接受頭,然後出站,使用<choose>策略來檢查變量,並且只應用轉換,如果接受標頭爲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> 
2

我意識到這是相當古老的,但我最近遇到了同樣的問題,從達雷爾提供的答案几乎爲我做了詭計。我必須將Accept頭從覆蓋改爲刪除。後端系統不喜歡收到任何Accept頭。對不起,發佈一個新的答案,我沒有足夠的代表評論。

<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="delete"> 
      </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>