[水煮 ASP.NET Web API2 方法論](12-1)創建 OData

来源:http://www.cnblogs.com/shuizhucode/archive/2016/11/18/6076238.html
-Advertisement-
Play Games

問題 怎樣用在 Web API 中創建 OData 服務。 解決方案 對於我們來說,在 Web API 中使用 OData最簡單的方式就是使用 ASP.NET 模板來創建Odata Controller。在 Controllers 文件夾上滑鼠右鍵->添加->新建項。 顯示一個如圖 12-1 的對話 ...


問題

  怎樣用在 Web API 中創建 OData 服務。

 

解決方案

  對於我們來說,在 Web API 中使用 OData最簡單的方式就是使用 ASP.NET 模板來創建Odata Controller。在 Controllers 文件夾上滑鼠右鍵->添加->新建項。

wKiom1glDKCzoR0BAAEYtJ6ZIOQ942.png

 

  顯示一個如圖 12-1 的對話框,在這裡我們可以選擇兩個 Web API 2 OData 相關的模板。Vistual Studio將會生成相關的 OData Controller,同時,從 NuGet 上下載 OData 需要的所有程式集。

 12-1. 使用模板添加 OData Controller

wKioL1glDMaxZzIIAAC5fDASuZ4568.png

 

  不過,這個模板僅僅對於 WEB Host ASP.NET Web API 托管在 ASP.NET Web 應用程式中)是可以用。對於 Web API 托管在其他地方,我們可以通過 NuGet 手動安裝 OData Microsoft.AspNet.OData 來開啟我們的OData 開發之旅。

 

工作原理

  OData 是一種通過 HTTP 公開豐富 API的標準化協議。OData 4.0 已經被 OASIS 國際開放標準聯盟批准,也被認為是 Web 界的 ODBC

 

Open Data ProtocolOData )可以創建基於REST 的數據服務,可以是資源,使用 URL 和定義的數據模型,可以通過 Web 客戶端使用簡單的 HTTP 消息來發佈和編輯。

 OData 4.0

http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html

 

小提示 OData 主頁 www.odata.org 裡面有所有感興趣的資源,他可以幫助我們瞭解 Odato 協議。

ASP.NET WWB API 2.2 支持 OData 4.0Microsoft.AspNet.OData NuGet 包),然而,之前的 Web API 支持的OData 3.0。如果我們要是指定引用 Mircosoft.Aspnet.WebApi.OData NuGet ,還是可以使用 OData 3.0

OData Controller 應該繼承自 ODataController 基類,而不是常規的ApiControllerASP.NET Web API 允許我們在一個項目中混合使用 OData Controller  傳統的 Controller,所以,我們可以在提供 OData Api 的同時提供常規 Api

Controller 繼承 ODataController 是有框架進行不同配置的。被稱為 ODataActionSelector  Odata IHttpAcionSelector 的實現類,是基於 Odata 路由的約定,以及一組特定的媒體類型格式化也是被預設替換的。所有的 OData 格式化程式都是 ODataMediaTypeFormatter 的變種,他可以處理 OData 指定的請求和相應格式,XML  JSON

 

代碼演示

  清單 12-1 展示了一個完成的功能,而且很典型的 ODataController  CRUD。在這樣的情況下,會通過ASP.NET 的模板根據 Player 實體和 EF 數據上下文生成 Controller

 

清單 12-1 典型的 ODataController

1 2 3 4 5 6 7 8 9 namespace BoiledCode.WebApi.Recipe.ODataDemo.Models {     public class Player     {         public int Id { getset; }         public string Name { getset; }         public string Team { getset; }     } }

 

wKioL1glDN-jaix-AAAmSQFySzs693.png-wh_50

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Web.Http; using System.Web.OData; using BoiledCode.WebApi.Recipe.ODataDemo.Models;    namespace BoiledCode.WebApi.Recipe.ODataDemo.Controllers {     /*     The WebApiConfig class may require additional changes to add a route for this controller. Merge these statements into the Register method of the WebApiConfig class as applicable. Note that OData URLs are case sensitive.        using System.Web.OData.Builder;     using System.Web.OData.Extensions;     using BoiledCode.WebApi.Recipe.ODataDemo.Models;     ODataConventionModelBuilder builder = new ODataConventionModelBuilder();     builder.EntitySet<Player>("Players");     config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());     */        public class PlayersController : ODataController     {         private readonly ApplicationDbContext db = new ApplicationDbContext();            // GET: odata/Players         [EnableQuery]         public IQueryable<Player> GetPlayers()         {             return db.Players;         }            // GET: odata/Players(5)         [EnableQuery]         public SingleResult<Player> GetPlayer([FromODataUri] int key)         {             return SingleResult.Create(db.Players.Where(player => player.Id == key));         }            // PUT: odata/Players(5)         public IHttpActionResult Put([FromODataUri] int key, Delta<Player> patch)         {             Validate(patch.GetEntity());                if (!ModelState.IsValid)             {                 return BadRequest(ModelState);             }                var player = db.Players.Find(key);             if (player == null)             {                 return NotFound();             }                patch.Put(player);                try             {                 db.SaveChanges();             }             catch (DbUpdateConcurrencyException)             {                 if (!PlayerExists(key))                 {                     return NotFound();                 }                 throw;             }                return Updated(player);         }            // POST: odata/Players         public IHttpActionResult Post(Player player)         {             if (!ModelState.IsValid)             {                 return BadRequest(ModelState);             }                db.Players.Add(player);             db.SaveChanges();                return Created(player);         }            // PATCH: odata/Players(5)         [AcceptVerbs("PATCH""MERGE")]         public IHttpActionResult Patch([FromODataUri] int key, Delta<Player> patch)         {             Validate(patch.GetEntity());                if (!ModelState.IsValid)             {                 return BadRequest(ModelState);             }                var player = db.Players.Find(key);             if (player == null)             {                 return NotFound();             }                patch.Patch(player);                try             {                 db.SaveChanges();             }             catch (DbUpdateConcurrencyException)             {                 if (!PlayerExists(key))                 {                     return NotFound();                 }                 throw;             }                return Updated(player);         }            // DELETE: odata/Players(5)         public IHttpActionResult Delete([FromODataUri] int key)         {             var player = db.Players.Find(key);             if (player == null)             {                 return NotFound();             }                db.Players.Remove(player);             db.SaveChanges();                return StatusCode(HttpStatusCode.NoContent);         }            protected override void Dispose(bool disposing)         {             if (disposing)             {                 db.Dispose();             }             base.Dispose(disposing);         }            private bool PlayerExists(int key)         {             return db.Players.Count(e => e.Id == key) > 0;         }     } }

 

這個控制器和正常的 Controller 非常相似,只有幾個地方是需要強調

  • OData 查詢語法是通過     EnableQueryAttribute 來啟用的。我們將在 12-3 來繼續討論。

  • OData 查詢語法不僅可以用在集合上也可以用在單個實體上,用在單個實體上的時候,只要實體使用  SingleResult<T> 就可以。關於這個我們也是在 12-3 來詳細介紹。

  •  URI 綁定的時候,需要使用     FromODataUriAttribute,而不是傳統的 Web API FormUriAttribute

  • OData Controller 一般是允許部分實體的更新。這個例子上,是通過 HTTP  PATCH  Delta<T>來實現部分更新。Delta<T> 是一種特殊的類型,可以用於比較兩個實體之間的差異,但是,他僅僅適用於     ODataMediaTypeFormatters 類型。

  很顯然,控制器並非萬能的。使用 OData 的最小要求就是為OData 創建一個實體數據模型(EDM)和 設置OData 路由。這些最終操作的都是 Web API HttpConfiguration 的實例。如清單 12-2 所示,我們會在下一次(12-2)來介紹 OData 路由。EDM 是用來為我們的服務定義 URI,以及提供語義描述(元數據)。

 

清單 12-1. 設置 EDM  OData 路由

1 2 3 4 5 6 7 8 9 10         public void SettingUpEdmRoyte()         {             var config = new HttpConfiguration();             //配置 Web API             var builder = new ODataConventionModelBuilder();             builder.EntitySet<Player>("Players");             // 第一個參數:路由名稱,第二個參數:OData 路由首碼             // players 資源可以被 /odata/players 訪問             config.MapODataServiceRoute("odata""odata", builder.GetEdmModel());         }

 

  這個 ODataConventionModelBuilder 類可以幫我們創建一個 EDM,我們不需要不必擔心名稱轉換,導航屬性,主鍵。如果我們需要自定義這些預設關係,那麼,我們就需要使用它的基類 ODataModelBuilder,而不是ODataConventionModelBuilder

  EntitySet方法添加實體並設置為 EDM 同時定義指定的 ODataController 來處理相應資源的 HTTP 請求,在我們的例子中就是 PlayersController


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第一步:網路連接,在我的上一篇博客中有介紹,不再多說。 網路連接的目的:為了能使用yum命令,在網上直接下載文件。 第二步:前往oracle官網下載12c database伺服器端的兩個文件:(安裝在Linux) linuxamd64_12102_database_1of2.zip linuxamd ...
  • Ctrl+r 實現快速檢索使用過的歷史命令。Ctrl+r中r是retrieve中r。Ctrl+a:游標回到命令行首。 (a:ahead)Ctrl+e:游標回到命令行尾。 (e:end)Ctrl+w: 刪除游標處到行首的字元。Ctrl+k:刪除游標處到行尾的字元。Ctrl+u:刪除整個命令行文本字元。... ...
  • 軟體列表軟體版本備註centos6.4 x86_6464位系統mysqlmysql5.5.49本機使用python2.7seafile 依賴pythonpip8.1.2安裝模塊使用python-imaging1.1.7python模塊mysql-python1.2.5python模塊 使用pip安裝... ...
  • 將相關命令寫下,留作參考 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 ...
  • 在上一篇文章中介紹了新手如何安裝Ubuntu14.04的雙系統,本文會說明Ubuntu系統下搜狗輸入法的安裝,並就我遇見的一些bug給出最簡單的解決辦法。 第一部分、搜狗輸入法的安裝 本身搜狗輸入法的安裝是非常簡單的,這裡只是就安裝過程中會出現的問題提供解決方案。 首先,下載linux下64位搜狗輸 ...
  • 01 Linux環境準備 (本文在win10上使用 VMware12 + Ubuntu14.04) 步驟: 步驟: 1、JDK安裝及相關配置 2、Tomcat安裝及相關配置 2、Tomcat安裝及相關配置 3、Mysql安裝及相關配置 3、Mysql安裝及相關配置 詳細步驟: 詳細步驟: 1、JDK ...
  • ASP.NET Core 1.1 Preview 1於2016年10月25日發佈。這個版本包括許多偉大的新功能以及許多錯誤修複和一般的增強。 要將現有項目更新到ASP.NET Core 1.1 Preview 1,您需要執行以下操作: 1. 下載並安裝更新的.NET Core 1.1 Prevew ... ...
  • 使用了第三方的JS庫或框架,在VS中編寫JS代碼,發現真是個悲劇,完全只能手打,智能感知沒了,這不符合VS的一貫做風只要在寫代碼的JS文件加上以下代碼,就可以有智能感知了 說明:path內為使用的第三方JS庫或框架的js文件,如果文件沒有和在編碼的JS在同一目錄下,則要補全路徑 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...