1. 程式人生 > >使用 ASP.NET Core MVC 創建 Web API——響應數據的內容協商(七)

使用 ASP.NET Core MVC 創建 Web API——響應數據的內容協商(七)

found 數據傳輸 tro mep res 實體對象 模型 log conn

使用 ASP.NET Core MVC 創建 Web API

使用 ASP.NET Core MVC 創建 Web API(一)

使用 ASP.NET Core MVC 創建 Web API(二)

使用 ASP.NET Core MVC 創建 Web API(三)

使用 ASP.NET Core MVC 創建 Web API(四)

使用 ASP.NET Core MVC 創建 Web API(五)

使用 ASP.NET Core MVC 創建 Web API(六)

ASP.NET Core MVC 包含對通過固定格式或根據客戶端規範來設置響應數據格式的內置支持。

ASP.NET Web API的內容協商(Content Negotiation)機制的理想情況是這樣的:客戶端在請求頭的Accept字段中指定什麽樣的MIME類型,Web API服務端就返回對應的MIME類型的內容(響應頭的中Content-Type就是Accept中指定的MIME類型)。而現實情況是,Web API服務端能返回什麽MIME類型的響應類型取決於有沒有對應這個MIME類型的MediaTypeFormatter。ASP.NET Core Web API的默認提供JsonMediaTypeFormatter,如果要支持 XmlMediaTypeFormatter需要進行配置。

ASP.NET Core MVC 使用的默認格式是 JSON。 內容協商由 ObjectResult 實現。 它還內置於從幫助程序方法(全部基於 ObjectResult)返回的特定於狀態代碼的操作結果中。 還可以返回一個模型類型(已定義為數據傳輸類型的類),框架將自動將其打包在 ObjectResult 中。

以下操作方法返回一個對象實例和 NotFound 幫助程序方法:

[HttpGet("{id}")]
        public async Task<ActionResult<Book>> GetBookItem(int
id) { var bookItem = await _context.Book.FindAsync(id); if (bookItem == null) { return NotFound(); } return bookItem; }

將返回 JSON 格式的響應,除非請求了另一個格式且服務器可以返回所請求格式。 可以使用 Rester工具創建包括 Accept 標頭的請求並指定另一種格式。 在此情況下,如果服務器有可以生成所請求格式的響應的格式化程序,則結果會以服務器首選的格式返回。

1) 在Visual Studio 2017中按F5,啟動BookApi應用程序。

2) 打開Firefox瀏覽器,並打開 Rester,在Reseter中,將 HTTP 方法設置為 GET

3) 然後在URL輸入框中輸入要獲取的對象URI,例如 http://localhost:5000/api/book/25

4) 選擇“Headers”選項卡,選擇“Accept”選項,並將值設置為 JSON (application/json)。

5) 使用鼠標點擊“Send”按鈕。請求將收到具有作書籍數據的“200 正常”響應。如下圖。

技術分享圖片

6) 選擇“Headers”選項卡,選擇“Accept”選項,並將值設置為 xml (application/xml)。

7) 使用鼠標點擊“Send”按鈕。請求將收到具有作書籍數據的“200 正常”響應。如下圖。我們雖然指定 Accept為 application/xml,但是在默認情況下,ASP.NET Core MVC 僅支持 JSON。所以,即使指定另一種格式,返回的結果仍然是 JSON 格式,而不是我們希望的xml。如下圖。

技術分享圖片

控制器操作可以返回 POCO(普通舊 CLR 對象),在這種情況下,ASP.NET Core MVC 將自動創建打包對象的 ObjectResult。 客戶端將獲取設有格式的序列化對象(默認為 JSON 格式,可以配置 XML 或其他格式)。 如果返回的對象為 null,那麽框架將返回 204 No Content 響應。

1) 在Visual Studio 2017中打開BookController.cs文件,添加以下 GetBook 方法返回實體對象,代碼如下:

[HttpGet("{id}")]
        public  Book GetBook(int id)
        {
            var bookItem =  _context.Book.Find(id);       
            return bookItem;
        }

2)在Visual Studio 2017中按F5啟動Web應用程序。

3) 打開瀏覽器,一並打開Rester。

4) 將 HTTP 方法設置為 GET。將請求 URL 設置為 http://localhost:5000/api/Book/25

5) 使用鼠標點擊“Send”按鈕。請求將收到具有作書籍數據的“200 正常”響應。如下圖。

技術分享圖片

6) 請求無效將收到“204 無內容”響應。 如下圖。

技術分享圖片

配置格式化程序

如果應用程序需要支持默認 JSON 格式以外的其他格式,那麽可以添加 NuGet 包並配置 MVC 來支持它們。輸入和輸出的格式化程序不同。輸入格式化程序由模型綁定使用;輸出格式化程序用來設置響應格式。 還可以配置自定義格式化程序。請求頭的Accept中除非指定為application/xml或者application/json,否則指定其它任何MIME,

添加 XML 格式支持

在Visual Studio 2017若要添加對 XML 格式的支持,請安裝 Microsoft.AspNetCore.Mvc.Formatters.Xml NuGet 包。

1. 在Visual Studio 2017的菜單>工具>選項對話框中,選擇“NuGet包管理器”中的常規,根據自己需要,設置默認包管理格式,如下圖。

技術分享圖片

2. 在解決方案資源管理器中,右鍵單擊“引用”,選擇“管理 NuGet 程序包”,如下圖。

技術分享圖片

3.將“nuget.org”選擇為“包源”,選擇“瀏覽”選項卡並搜索“Microsoft.AspNetCore.Mvc.Formatters.Xml”,在列表中選擇該包,然後選擇“安裝”,如下圖。

技術分享圖片

4.在Visual Studio 2017中打開Startup.cs文件,將 XmlSerializerFormatters 配置添加到 Startup類的ConfigureServices方法中。代碼如下:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<BookContext>(options =>   options.UseSqlServer(Configuration.GetConnectionString("BookContext"))); 
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddXmlSerializerFormatters(); }

或者,可以僅添加輸出格式化程序:

services.AddMvc(options =>
{
    options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});

通過上面的代碼我們添加了對 XML 格式的支持,控制器方法會基於請求的 Accept 標頭返回相應的格式。接下來我們來測試一下。

1) 在Visual Studio 2017中按F5,啟動BookApi應用程序。

2) 打開Firefox瀏覽器,並打開 Rester,在Reseter中,將 HTTP 方法設置為 GET

3) 選擇“Headers”選項卡,選擇“Accept”選項,並將值設置為 xml (application/xml)。

4) 使用鼠標左鍵,單擊“SEND”按鈕。 響應返回200,響應窗格顯示 Content-Type: application/xml 標頭,且 Book 對象已序列化為 XML。如下圖。

技術分享圖片

5) 選擇“Headers”選項卡,選擇“Accept”選項,並將值設置為 JSON (application/json)。

6) 使用鼠標左鍵,單擊“SEND”按鈕。 響應返回200,響應窗格顯示 Content-Type: application/json 標頭,且 Book 對象已序列化為 JSON。如下圖。從圖片中可以看到請求了設置 Accept: application/json 的標頭,且響應也將它指定為其 Content-TypeBOOK 對象以 JSON 格式顯示在響應正文中。

技術分享圖片

內容協商過程

內容協商僅在 Accept 標頭出現在請求中時發生。 請求包含 accept 標頭時,框架會以最佳順序枚舉 accept 標頭中的媒體類型,並且嘗試查找可以生成一種由 accept 標頭指定格式的響應的格式化程序。 如果未找到可以滿足客戶端請求的格式化程序,框架將嘗試找到第一個可以生成響應的格式化程序(除非開發人員配置 MvcOptions 上的選項以返回“406 不可接受”)。 如果請求指定 XML,但是未配置 XML 格式化程序,那麽將使用 JSON 格式化程序。 一般來說,如果沒有配置可以提供所請求格式的格式化程序,那麽使用第一個可以設置對象格式的格式化程序。 如果不提供任何標頭,則將使用第一個可以處理要返回的對象的格式化程序來序列化響應。 在此情況下,沒有任何協商發生 - 服務器確定將使用的格式。

如果 Accept 標頭包含 */*,則將忽略該標頭,除非 RespectBrowserAcceptHeaderMvcOptions 上設置為 true。

使用 ASP.NET Core MVC 創建 Web API——響應數據的內容協商(七)