[水煮 ASP.NET Web API2 方法論](12-2)OData 支持的 Function 和 Action

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

問題 在 Web API 中使用 OData Function 和 Action。 解決方案 可以通過 ODataModelBuilder,使用 OData 構建 ASP.NET Web API, EntityCollectionConfiguration,EnityTypeConfiguratio ...


問題

在 Web API 中使用 OData Function 和 Action。

 

解決方案

可以通過 ODataModelBuilder,使用 OData 構建 ASP.NET Web API, EntityCollectionConfiguration,EnityTypeConfiguration 類中提供的一系列 Function 和 Action 來自定義 Function 和 Action。

當我們都建自己的 ODataModelBuilder 的時候,可以指定 Function 或 Action 名稱並定義他們的輸入參數。如清單12-12 所示。

清單 12-12. 

 1             var ODataBuilder = new ODataConventionModelBuilder();
 2 
 3             ODataBuilder.EntitySet<Player>("Players");
 4 
 5             var player = ODataBuilder.EntityType<Player>();
 6 
 7             // Function – 讀取數據
 8 
 9             player.Function("PercentageOfAllGoals").Returns<double>();
10 
11             // Action – 請求操作
12 
13             player.Action("TradePlayer").Parameter<string>("NewTeam");

 

Controller Action 和 OData Function/Action 之間是通過命名的約定建立關聯,因此,我們需要在 OData 的 controller 中添加合適的 Action。

 

工作原理

ASP.NET WEB API 從 2.2 版本開始支持 OData,而且,已經成為 OData 3.0 規範的一部分。另一方面,在之前 Web API 中 OData 的 Action 也是可以使用的。

我們是可以以 Web API Action 的形式定義 OData Function/Action 同時暴露給客戶端訪問。

使用 Action 或 Function 的主要優勢是,我們可以將查詢的責任轉交給伺服器,尤其是複雜查詢的時候,可以減輕客戶端的不必要的麻煩。

OData 的 Action 和 Function 是有點不一樣的;他們都是在規範中被定義的“一組可以被執或可以作為服務或可以作為資源的操作的擴展”。主要的不同是

  • Function:可以能沒有什麼結果,但是必須有返回值
  • Action:可以對伺服器產生影響,但是不能有返回值
  • 另外,Function 可以在 $filter 中被調用

在實現了 OData 的 ASP.NET WEB API 中,Action 和 Function 是連同 OData 約定一起被定義,他們是通過 ODataConventionModelBuilder 的實例定義。WEB API OData 的構建支持三種類型(級別)的操作:

  • 服務 Action/Function:ODataModelBuilder 直接定義
  • 集合 Action/Function:EntityCollectionConfiguration 直接定義
  • 實體 Action/Function:EntityTypeConfiguration直接定義

 

代碼演示

 

如清單 12-13 所示,一個簡單的數據集合,為了演示的方面,在 Controller 中通過記憶體進行數據的操作,還有一個 Player 的 DTO 的類。

我們就使用這些代碼模擬 OData 的三種類型:服務,集合,實體綁定。演示中主要關註在 Function 上,但是, Action 的定義和使用也是幾乎一樣的。也就是說,在所有使用 Function 聲明的方法的地方,都換成 Action 聲明的方法是沒有毛病的。

 

清單 12-13. 記憶體數據和實體模型

 1     public class Player
 2     {
 3         public int Id { get; set; }
 4 
 5         public string Name { get; set; }
 6 
 7         public string Team { get; set; }
 8 
 9         public SkaterStat Stats { get; set; }
10     }
11 
12     public class SkaterStat
13     {
14         public int Goals { get; set; }
15 
16         public int Assists { get; set; }
17 
18         public int GamesPlayed { get; set; }
19     }
20 
21     public class PlayersController : ODataController
22     {
23         private static List<Player> _players = new List<Player>
24         {
25             new Player
26             {
27                 Id = 1,
28                 Name = "Filip",
29                 Team = "Whales",
30                 Stats = new SkaterStat
31                 {
32                     GamesPlayed = 82,
33                     Goals = 37,
34                     Assists = 43
35                 }
36             },
37             new Player
38             {
39                 Id = 2,
40                 Name = "Felix",
41                 Team = "Whales",
42                 Stats = new SkaterStat
43                 {
44                     GamesPlayed = 80,
45                     Goals = 30,
46                     Assists = 31
47                 }
48             new Player
49 {
50     Id        = 3,
51                 Name = "Luiz",
52                 Team = "Dolphins",
53                 Stats = new SkaterStat
54                 {
55                     GamesPlayed = 78,
56                     Goals = 20,
57                     Assists = 30
58                 }
59             },
60             new Player
61             {
62                 Id = 4,
63                 Name = "Terry",
64                 Team = "Dolphins",
65                 Stats = new SkaterStat
66                 {
67                     GamesPlayed = 58,
68                     Goals = 19,
69                     Assists = 30
70                 }
71             }
72         };
73     }

 

前面提到的 Function 方法,來自於 ODataModelBuilder;EntityCollectionConfiguration,EntityTypeConfiguration,都返回一個 FunctionConfiguration 的實例,我們就是用它來配置我們的 Function,例如,在 $filter 中是否支持 Function,接收什麼樣的參數,應該返回什麼。例如,這個演示的 Startup 類中定義了 ODataModelBuilder的 三個 OData  Function 類型和一個實體類型,如清單 12-14 所示。

 

清單 12-14 OData Function 服務、集合、實體

 1     public class Startup
 2     {
 3 
 4         public void Configuration(IAppBuilder builder)
 5         {
 6 
 7             var ODataBuilder = new ODataConventionModelBuilder();
 8 
 9             ODataBuilder.EntitySet<Player>("Players");
10 
11             var player = ODataBuilder.EntityType<Player>();
12 
13             /* 集合 Function */
14 
15             player.Collection.Function("TopPpg").ReturnsCollection<Player>();
16 
17             /* 實體 Function */
18 
19             player.Function("PercentageOfAllGoals").Returns<double>();
20 
21             /* 服務 Function */
22 
23             var serviceFunc = ODataBuilder.Function("TotalTeamPoints");
24 
25             serviceFunc.Returns<int>().Parameter<string>("team");
26 
27             serviceFunc.IncludeInServiceDocument = true;
28 
29             var edm = ODataBuilder.GetEdmModel();
30 
31             var config = new HttpConfiguration();
32 
33             config.MapODataServiceRoute("Default OData", "OData", edm);
34 
35             builder.UseWebApi(config);
36 
37         }
38 
39     }

 

TopPpg 是一個集合 Function,他將返回每場比賽最高分(得分+助攻)比例 player 的集合。PercentageOfAllGoals 是一個實體 Function,返回每場比賽給定參賽者相對所有得分的分數比例。這個 Function 需要客戶端傳一個 key(player ID),但是,需要註意的是,這個 key 是實體對象的 Id,不需要在 Function 中特殊指明。最後,TotalTeamPoints 是無限制的服務 Function,也就是說,不是特指某一個 player,而是傳入一個隊名最為參數,同時返回整個隊內所有隊員分數(得分+助攻)的總和。另外,TotalTeamPoints 也會包含在文檔服務中,/OData/$metadata ,作為 Function 入口。

這些 Function 在 Action 中都是使用的 LINQ 表達式。無限制服務的 Function 使用了 ODataRoute 屬性,因為預設的 EMD 驅動路由約定不能完成整個功能。

 

12-15/ 使用 OData Function 來暴露 Controller 的 Action

 1         [HttpGet]
 2         public IEnumerable<Player> TopPpg()
 3         {
 4             var result = _players.OrderByDescending(x => (double)(x.Stats.Goals + x.Stats.Assists) / (double)x.Stats.GamesPlayed).Take(3);
 5             return (result);
 6         }
 7 
 8 
 9         [HttpGet]
10         public IHttpActionResult PercentageOfAllGoals(int key)
11         {
12             var player = _players.FirstOrDefault(x => x.Id == key);
13             if (player == null)
14                 return (NotFound());
15             var result = (double)player.Stats.Goals / (double)_players.Sum(x => x.Stats.Goals) * 100;
16             return (Ok(result));
17         }
18 
19 
20         [HttpGet]
21         [ODataRoute("TotalTeamPoints(team={team})")]
22         public int TotalTeamPoints([FromODataUri] string team)
23         {
24             var result = _players.Where(x => string.Equals(x.Team, team, StringComparison.
25                                      InvariantCultureIgnoreCase))
26                      .Sum(x => x.Stats.Goals + x.Stats.Assists);
27             return (result);
28         }

 

在這些地方,可以在 URI 中使用 Function 名稱來調用他們。根據規範,調用 OData Function 的時候需要使用括弧:

  • /OData/Players/Default.TopPpg()
  • /OData/Players(1)/Default.PercentageOfAllGoals()
  • /OData/TotalTeamPoints(team='Whales')

 關於 OData 在 ASP.NET WEB API 中的介紹就此告一段落,接下來,一段時間將介紹關於 Route 的東西。

 


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

-Advertisement-
Play Games
更多相關文章
  • 在Ubuntu中第一次使用VIM編輯器發現好強大,打算在Win7中安裝,其中遇到一些小問題,下邊介紹詳細的安裝過程和遇到的問題。 1-安裝 首先發現Github中有一款中意的作者,並且他開源的基本插件都集合了。 地址:https://github.com/DemonCloud/Aix-Vim(下載地 ...
  • web.config <configuration> <connectionStrings> <add name="constr" connectionString="server=.\sqlexpress;database=db2016;uid=sa;pwd=123;" /> <add name= ...
  • Public Class Profile Private Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As Stri ...
  • 現在流行的系統一般都採用依賴註入的實現方式,利用DI容器來直接獲取所用到的類/介面的實例。.net core也一樣採用DI的方式,提供了DI容器的介面IServiceCollection,並提供了基於該介面的預設實現ServiceCollection。 這樣我們就可以不再像以前一樣,需要引入第三方的 ...
  • 1.界面 <UserControl x:Class="HKDCMS.Client.Demo.UIViews.UIControls.AboutUsControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xml ...
  • In Windows 8 & 10, you have to right-click devenv.exe and select "Troubleshoot compatibility". 轉自 http://stackoverflow.com/questions/12257110/can-you- ...
  • 註冊的伺服器和中間件共同構成了ASP.NET Core用於處理請求的管道, 這樣一個管道是在我們啟動作為應用宿主的WebHost時構建出來的。要深刻瞭解這個管道是如何被構建出來的,我們就必須對WebHost和它的創建者WebHostBuilder這個重要的對象具有深刻的理解。[ ...
  • 利用 async & await 進行非同步 IO 操作 【博主】反骨仔 【出處】http://www.cnblogs.com/liqingwen/p/6082673.html 序 上次,博主通過《利用 async & await 的非同步編程》這篇點睛之作初步介紹了 async & await 的基本 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...