RestfulApi 學習筆記——內容協商(三)

前言

什麼是內容協商呢?是這樣的,我們在請求的時候都有兩個屬性,一個是Content-Type,另一個是accept,這兩個什麼意思呢?

content-type 這個是表示自己傳輸的是什麼內容,就像我們自動綁定參數的時候,我們既要知道從哪裏獲取,也要知道如何解析啊,不然該按哪種方式提取呢。

accept 這個是就像這個英文但是意思一樣,接受,表示接受什麼樣的類型的返回類型。其實我們返回的全部是字節,到了我們前端轉換爲字符流,那麼根據這個accept 再來解析。

看一下content-type 的參數:

Content-Type:type/subtype ;parameter

type:主類型,任意的字符串,如text,如果是號代表所有;
subtype:子類型,任意的字符串,如html,如果是
號代表所有,用“/”與主類型隔開;
parameter:可選參數,如charset,boundary等。

這裏舉一個content-type 的例子哈:

Content-Type application/x-www-form-urlencoded; charset=UTF-8

這個是什麼意思呢?比如說,有幾個參數key=1 name=x,那麼它將會這樣傳輸key=1&name=x,然後放在body中,但是放之前會將一些特殊字符轉碼,比如說空格轉換爲%20。

再舉一個例子吧:

Content-Type multipart/form-data;

這個相比大家非常的熟悉了,就是大名鼎鼎的form-data,這個和json還有xml不同,這個可以傳遞文件,所以主類型叫做多媒體類型multipart。

首先生成了一個 boundary 用於分割不同的字段,在請求實體裏每個參數以------boundary開始,然後是附加信息和參數名,然後是空行,最後是參數內容。多個參數將會有多個boundary塊。如果參數是文件會有特別的文件域。最後以------boundary–爲結束標識。

爲了更加形象的展示出,決定去網上弄一張圖片。

大概是這樣了。其他的就不介紹了,accept和這個差不多。下面就進入正文,我們寫代碼如何和後臺協商呢?至於具體的解析,我們就不要去寫了,畢竟夠用,沒必要自己去定義類型吧。

正文

首先我們要有一個步驟,或者說錯誤性驗證。

就是如假設Content-Type 客戶端填寫的內容,不被我們服務器接受,那麼我們作爲服務器,我們要怎麼做?

我們這個時候應該返回415錯誤,也就是Unsupported Media Type就是服務器不支持該媒體類型。

如果accept 無法滿足客戶端的請求,那麼就應該返回406,服務器無法滿足客戶端,也急速no acceptable,不支持吧。

舉個例子,我要請求某個公司的資料,然後返回application/json:

這時候其樂融融,滿足了,那麼我現在要返回xml。這時候出現問題了,明明我要的是xml,你給我json,我以爲自己得到的是xml,結果解析失敗。

這個時候就是服務器問題了,因爲服務器沒有提示406,不能滿足對方。

在ConfigureServices 中配置一下,如下:

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

再請求一次406了,如下:

如果針對xml格式的話,我們如何返回json 又能返回xml,是寫兩個方法嗎?不是的,我們可以做一些配置,讓.net core框架自動來轉換,果然框架纔是第一生產力。

只要加剛纔的基礎上加上:setup.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter());。

那麼如果你想默認的返回格式是xml,那麼你應該xml放在第一位:setup.OutputFormatters.Add(0,new XmlDataContractSerializerOutputFormatter())

這裏簡單介紹一下,.net core的OutputFormatters 表示的是輸出格式化,那麼還有輸入格式化。InputFormatters 就是對media type的控制了。

那麼看一下效果吧:

有些人可能這樣沒有效果,那麼你返回可能是這樣寫的:return new JsonResult(company);,這個時候已經寫死了格式,返回的還是json,並且服務器支持了xml所以也不會406,所以還是建議這樣寫ok(company)。

那麼到這裏就介紹這一小結,這裏就有人問了,爲啥不介紹Content-Type呢?因爲系統默認支持全部,當然你可以通過InputFormatters 刪除一些。。。比如setup.InputFormatters.Remove..

記得我前面提及過,apicontroller可以自動幫我們處理40x錯誤,比如415,默認解析是form-data,如果你沒有傳任何form-data,那麼就是爲空,空的是不可能是formdata類型,那麼服務器解析不了那麼就是415,這個新手還是遇到概率還是很高的。如果你寫的int id,傳過來的是一個string,那麼會返回400,One or more validation errors occurred。

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