ASP.NET Core MVC 包含對通過固定格式或根據客戶端規範來設置響應數據格式的內置支持。 ASP.NET Web API的內容協商(Content Negotiation)機制的理想情況是這樣的:客戶端在請求頭的Accept欄位中指定什麼樣的MIME類型,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 創建 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-Type
。 BOOK
對象以 JSON 格式顯示在響應正文中。
內容協商過程
內容協商僅在 Accept
標頭出現在請求中時發生。 請求包含 accept 標頭時,框架會以最佳順序枚舉 accept 標頭中的媒體類型,並且嘗試查找可以生成一種由 accept 標頭指定格式的響應的格式化程式。 如果未找到可以滿足客戶端請求的格式化程式,框架將嘗試找到第一個可以生成響應的格式化程式(除非開發人員配置 MvcOptions
上的選項以返回“406 不可接受”)。 如果請求指定 XML,但是未配置 XML 格式化程式,那麼將使用 JSON 格式化程式。 一般來說,如果沒有配置可以提供所請求格式的格式化程式,那麼使用第一個可以設置對象格式的格式化程式。 如果不提供任何標頭,則將使用第一個可以處理要返回的對象的格式化程式來序列化響應。 在此情況下,沒有任何協商發生 - 伺服器確定將使用的格式。
如果 Accept 標頭包含 */*
,則將忽略該標頭,除非 RespectBrowserAcceptHeader
在 MvcOptions
上設置為 true。