使用ASP.NET Core 3.x 構建 RESTful API P7 P8 內容協商

使用ASP.NET Core 3.x 構建 RESTful API P7 P8 內容協商

內容協商 (Content Negotiation)

人們經常將 RESTful APIJson 聯繫在一起,是因爲 Json
RESTful API 表述,結果的一種方式,但是 RESTful API表述結果,不僅僅會使用 Json ,也有可能會使用 XML ,以及一些其它自定義的數據格式,那麼到底需要 RESTful API 返回什麼樣的數據格式類型呢?那麼這就叫做 內容協商,即 API 消費者需要明確的告知, API 它需要什麼樣的返回結果的數據格式,以便返回的結果,能夠得到順利的解析.

  • 內容協商:針對一個響應,當有多種表示格式可用的時候,選取最佳的一個表述.
Accept Header

在請求報文中 Accept Hander 是用來告訴Api,消費者需要API來返回什麼樣格式的數據.

  • Media Type (媒體類型)
    • application/json
    • application/xml
    • ...
  • 如果消費者沒有告訴 API 它需要的數據格式,那麼 API 會以 API 自己默認的數據格式返回數據.
  • 如果 消費者 明確告知了 API 自己需要的數據格式,但是 API 不支持這種數據格式,那麼 API 就應該返回 406HTTP Status Code ,即 Not Acceptable
  • 輸出格式
  • 在 ASP .NET Core 裏面對應的就是 Output Formatters
Content-Type Hander

在請求報文中 Content-Type 是用來告訴 API,消費者傳遞過來的數據的格式是什麼樣的,以便 API 可以方便的解析消費者的請求參數.

  • Media Type(媒體類型)

    • application/json
    • application/xml
    • ...
  • 輸出格式

  • ASP .NET Core 裏面對應的就是Input formatters.

Accept Hander 與 Content-Type Hander 的應用

在默認情況下 ASP .Net Core 使用 JSON 作爲數據輸入和輸出的格式化器.

下面開始寫代碼對上理論進行驗證

如當消費者要求的返回格式,API 不支持,那麼 API 應該返回相應的 HTTP 狀態碼.

爲此在 ASP .Net Core 中,我們需要在 Startup.cs 文件的 ConfigureServices 方法中編寫以下代碼:

 services.AddControllers(setup =>
            {
                //例子:當消費者要求返回的數據格式是json時,如果服務器端默認的就是xml格式,而且僅僅只支持xml格式,
                //那麼默認的就會將xml格式返回回去,並且不會返回406狀態碼,所以ReturnHttpNotAcceptable的默認值就是false
                //setup.ReturnHttpNotAcceptable = false;

                //當爲true時,表示當消費者要求的返回的數據類型,與數據庫支持的返回的數據類型不一致時,
                //就會返回 HTTP 狀態碼 406 ,也就是NotAcceptable
                setup.ReturnHttpNotAcceptable = true;
            });

當我們將 ReturnHttpNotAcceptable 的值設置爲true時,表示當消費者要求返回的數據格式,不被服務器所支持,那麼服務器就會返回406,如圖:

返回406
返回406

那麼我們讓我們的 API 既支持json格式的返回,也支持xml格式的返回呢?
我們可以將代碼這麼寫,如下:

     services.AddControllers(setup =>
            {
                //例子:當消費者要求返回的數據格式是json時,如果服務器端默認的就是xml格式,而且僅僅只支持xml格式,
                //那麼默認的就會將xml格式返回回去,並且不會返回406狀態碼,所以ReturnHttpNotAcceptable的默認值就是false
                //setup.ReturnHttpNotAcceptable = false;

                //當爲true時,表示當消費者要求的返回的數據類型,與數據庫支持的返回的數據類型不一致時,
                //就會返回 HTTP 狀態碼 406 ,也就是NotAcceptable
                setup.ReturnHttpNotAcceptable = true;


                //OutputFormatters是一個集合,這個集合裏面可以放置多個格式化器,用來支持多種消費者要求的返回格式,
                //這OutputFormatters中的第一個元素設置,就是這個集合默認的返回格式的格式化器,默認情況下OutputFormatters
                //中只有一個json格式化器.

                //下面我們添加對xml格式化器的支持
                //setup.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());

                //如果我們想添加xml格式化器,並使其成爲默認的數據格式化器,那麼我們使用如下寫法即可:
                //那麼當消費者沒有要求返回格式時,API會默認返回xml格式的數據.
                setup.OutputFormatters.Insert(0, new XmlDataContractSerializerOutputFormatter());
            });

請求返回的數據如下:
返回信息

請求返回的數據格式如下:
返回格式

此時我們要求 API 返回Json格式的數據也是可以的,因爲 API也支持了返回Json的設置,如下:
返回json的數據格式

此處我們需要注意:千萬不能在Action中使用return new JsonResult(對象);的形式來返回數據,否則就不能根據消費者要求的數據格式來返回數據了.

那麼我們如何支持輸入參數的數據格式的支持呢?
使用方式和 OutputFormatters是一樣的存在一個叫InputFormatters,它的使用方式和OutputFormatters, 是一樣的,代碼如下:

 //添加對請求參數格式是xml的支持
                setup.InputFormatters.Insert(0,new XmlDataContractSerializerInputFormatter(setup));

但是上述寫法都只是 ASP .Net Core 3.x 之前的寫法,在3.x 之後的寫法是這樣的,代碼如下:

services.AddControllers(setup =>
            {
             
                setup.ReturnHttpNotAcceptable = true;
                
            }).AddXmlDataContractSerializerFormatters();

我們可以接在 AddControllers() 方法之後,接着寫 .AddXmlDataContractSerializerFormatters()方法即可,它既表明支持消費者傳入的參數是xml格式,也支持消費者要求的返回數據格式是xml.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章