[水煮 ASP.NET Web API2 方法論](12-2)管理 OData 路由

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

問題 如何控制 OData 路由 解決方案 為了註冊路由,可以使用 HttpConfigurationExtension 類中 MapODataServiceRoute 的擴展方法。對於單一路由這樣做足以,其餘的處理由實體數據模型來處理。 從 ASP.NET Web API 2.2 開始支持 ODa ...


問題

如何控制 OData 路由

 

解決方案

為了註冊路由,可以使用  HttpConfigurationExtension 類中 MapODataServiceRoute 的擴展方法。對於單一路由這樣做足以,其餘的處理由實體數據模型來處理。

            config.MapODataServiceRoute("OData", "OData", builder.GetEdmModel());

從 ASP.NET Web API 2.2 開始支持 OData 直接聲明路由,在 Action 上使用 ODataRouteAttribute。這和常規的屬性路由一樣,可以通過 ODataRoutePrefixAttribute 在 Controller 級別設置路由首碼.

1         [ODataRoute("Players")]
2 
3         public IQueryable<Player> GetAllPlayers()
4 
5         {
6 
7             // 忽略
8 
9         }

 

工作原理

OData 在 Web API 中路由是通過 ODataRoute 類實現的,其實,他是 HttpRoute 的一個子類。定製路由需要支持 ODataPathRouteConstraint,他是 OData 制定的,是IHttpRouteConstrain 的實現類,是為了確保所有的  OData 屬性或 OData 路由約定在路由匹配後能夠設置到 HttpRequestMessage 上。

ODataPath 類是用來包裝轉換 OData 資源路徑,並以強類型的方式公開段(segment)。按約定,ASP.NET Web API 使用資源路徑(URI 的一部分,例如,/Player),他是基於實體數據模型來映射到相應的 Controller。然後,動詞依據動作選擇在 Controller 中找到相應的 Action。此外,在 Web API 中 OData 可以使用自定義路由,這些路由都會影響動作選擇。

 

小提示 更多關於 OData 路由約定的信息,請戳這裡

https://www.asp.net/web-api/overview/OData-support-in-aspnet-web-api/OData-routing-conventions

 

我們可以通過我們自己的 IODataRoutingConvertion 重寫 OData 路由行為、實現自定義 OData Controller、實現動作選擇,如清單 12-3 所示

 

清單 12-3 IODataRoutingConvention 定義

 

 1     public interface IODataRoutingConvention
 2 
 3     {
 4 
 5         string SelectController(ODataPath ODataPath, HttpRequestMessage request);
 6 
 7         string SelectAction(ODataPath ODataPath, HttpControllerContext controllerContext,
 8 
 9         ILookup<string, HttpActionDescriptor> actionMap);
10 
11     }

 

當我們定義 OData 路由時,可以通過 MapODataServiceRoue 擴展方法來自定義路由約定;其中個的一個重載方法就是 使用 IODataRoutingConvention 的集合作為參數的方法。如果沒有傳值(例如,在使用 MapODataServiceRoute),那麼,Web API 將在內部調用靜態的 ODataRoutingConventions。CreateDefaultWithAttributeRouting 只使用預設的內建路由約定。

在 OData 中屬性路由是 IDataRoutingConvention 的另一個版本-AttributeRoutingCinvention。他會查找所有 ODataRouteAttribute 的用法,使用 Dictionary<ODataPathTemplate,HttpActionDescriptot> 的形式建立適當的映射關係。如果進來的請求與當前 HTTP 請求的 ODataPath 匹配,那麼,與此相關的 HttpActionDescriptor Controller 將會被選翻牌子來處理請求。

屬性路由對於非標準路由來說是不錯的選擇,例如,使用非綁定的 OData 功能或 Action 的時候。嘗試使用集中路由的方式進行路由,就需要自定義路由約定,然而,屬性路由可以使用 ODataRouteAttribute 相關方法,用很簡單的聲明方式直接完成。

需要註意的是屬性路由與常規路由不同,他是預設啟用的。也就是說,除非我們重寫預設的 IODataRoutingConventions,否則,Web API 會調用 ODataRoutingConvents。無論什麼時候使用 MapODataServiceRoute 方法,CreateDefaultWithAttributeRouting 內部都會確保被 Web API OData 使用的 AttributeRoutingConvention 包含在約定的集合中。如清單 12-4 所示,摘錄自 Web API 源碼。

 

清單 12-4 ODataRoutingConvrention 類,確保 AttributeRoutingConvention 被包含。

 1     public static class ODataRoutingConventions
 2 
 3     {
 4 
 5         public static IList<IODataRoutingConvention> CreateDefaultWithAttributeRouting(
 6 
 7         HttpConfiguration configuration,
 8 
 9         IEdmModel model)
10 
11         {
12 
13             if (configuration == null)
14 
15             {
16 
17                 throw Error.ArgumentNull("configuration");
18 
19             }
20 
21             if (model == null)
22 
23             {
24 
25                 throw Error.ArgumentNull("model");
26 
27             }
28 
29             IList<IODataRoutingConvention> routingConventions = CreateDefault();
30 
31             AttributeRoutingConvention routingConvention = new AttributeRoutingConvention(model,
32 
33             configuration);
34 
35             routingConventions.Insert(0, routingConvention);
36 
37             return routingConventions;
38 
39         }
40 
41         public static IList<IODataRoutingConvention> CreateDefault()
42 
43         {
44 
45             return new List<IODataRoutingConvention>()
46 
47             {
48 
49                 new MetadataRoutingConvention(),
50 
51                 new EntitySetRoutingConvention(),
52 
53                 new SingletonRoutingConvention(),
54 
55                 new EntityRoutingConvention(),
56 
57                 new NavigationRoutingConvention(),
58 
59                 new PropertyRoutingConvention(),
60 
61                 new RefRoutingConvention(),
62 
63                 new ActionRoutingConvention(),
64 
65                 new FunctionRoutingConvention(),
66 
67                 new UnmappedRequestRoutingConvention()
68 
69             };
70 
71         }
72 
73     }

 

 

結果就是,在應用程式啟動,不在需要調用任何其他的方法通知框架掃描所有的路由屬性。事實上,只有這樣,才能在最開始的地方獲取屬性路由並調用 MapODataServiceRoute.

 

代碼演示

為了介紹 OData Web API 的集中路由,我們只需要在 HttpConfiguration 中調用 MapODataServiceRoute 和傳路由首碼,以及我們的 IEdmModel。一個完整的啟動類列子,使用簡單的 OData 實體和集中路由,如清單 12-5 所示,使用 Player 實體。

 

清單 12-5. 聲明一個基本的 OData 路由啟動類

 1     public class Startup
 2 
 3     {
 4 
 5         public void Configuration(IAppBuilder builder)
 6 
 7         {
 8 
 9             var ODataBuilder = new ODataConventionModelBuilder();
10 
11             ODataBuilder.EntitySet<Player>("Players");
12 
13             var edm = ODataBuilder.GetEdmModel();
14 
15             var config = new HttpConfiguration();
16 
17             config.MapODataServiceRoute("Default OData", "OData", edm);
18 
19             builder.UseWebApi(config);
20 
21         }
22 
23     }
24 
25     public class Player
26 
27     {
28 
29         public int Id { get; set; }
30 
31         public string Name { get; set; }
32 
33         public string Team { get; set; }
34 
35     }

 

允許我們使用所有預設的內建路由約定,例如,

• myapi.com/OData/Players

• myapi.com/OData/Players(key)

• myapi.com/OData/Players(key)/{navigation property | property}

• myapi.com/OData/Players(key)/{function | action}

 

註意 預設的 Web API OData 路由約定使用了 key 的概念,不是 ID,所以我們 Controller 的 Action 應該接收一個叫做 Key 的參數。

 

清單 12-6 展示了 ODataController 使用兩個 Action 方法。這兩個方法都是通過屬性路由的方式聲明瞭 OData 路由。

 

清單 12-6. OData Controller 使用屬性路由的例子

 1     [ODataRoutePrefix("Players")]
 2 
 3     public class PlayersController : ODataController
 4 
 5     {
 6 
 7         private readonly PlayersContext _players = new PlayersContext();
 8 
 9         [EnableQuery]
10 
11         [ODataRoute]
12 
13         public IQueryable<Player> GetAllPlayers()
14 
15         {
16 
17             return _players.AsQueryable();
18 
19         }
20 
21         [EnableQuery]
22 
23         [ODataRoute("({key})")]
24 
25         public SingleResult<Player> GetSinglePlayers(int key)
26 
27         {
28 
29             return SingleResult.Create(_players.Where(x => x.Id == key).AsQueryable());
30 
31         }
32 
33     }

 


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

-Advertisement-
Play Games
更多相關文章
  • 1.自定義listview,首先在activity.xml中插入一個listview,可以用android:divider=“”設置分割線顏色樣式,android:dividerHeight=""設置分割線高度。 2.新建viewholder_item.xml設計每行Item顯示的樣式佈局。 3.自 ...
  • Intent在活動的操作 作用: Itent是Android程式中各個組件直接交換的一個重要方式可以指定當前組件要執行任務同時也可以給各個組件直接進行數據交互 同時Intent啟動往往可以啟動活動,啟動服務,以及發送廣播等場景 分類 1.顯示Intent和隱示Intent 顯示Intent操作 1. ...
  • 1.Hadoop是什麼? 適合大數據的分散式存儲與計算平臺 HDFS: Hadoop Distributed File System分散式文件系統 MapReduce:並行計算框架 2.Hadoop生態圈 ①HBase Google Bigtable的開源實現 列式資料庫 可集群化 可以使用shel ...
  • 1.存儲與文件系統 存儲設備 存儲設備(常見的是磁碟/硬碟,固態硬碟) 文件系統 文件系統是操作系統用於存儲設備或分區上的文件的方法和數據結構 分散式文件系統 文件系統管理的物理存儲資源不一定直接連接在本地節點上,而是通過網路與節點相連 2.分散式文件系統 3.常見的分散式文件系統有: GFS: G ...
  • Database Configuration Assistant安裝失敗 向廣大園友求助 ...
  • 前面的話 對於前端工程師來說,資料庫並不是主要技能點,但是基本的增刪改查操作還是需要瞭解的。小火柴將mysql資料庫的學習記錄整理如下 目錄 前端學資料庫之基礎操作 前端學資料庫之數據類型 前端學資料庫之數據表操作 前端學資料庫之記錄操作 前端學資料庫之中文亂碼 前端學資料庫之子查詢 前端學資料庫之 ...
  • × 目錄 [1]存儲過程 [2]存儲引擎 前面的話 我們經常會對數據表進行插入、刪除、更新及查找的工作,即我們常說的CURD。其實,當我們輸入命令時,mysql引擎會按照下圖進行操作 如果我們省略了分析和編譯的環節,那麼執行效率將大大提高。這就需要下麵介紹的存儲來實現 存儲過程 存儲過程是SQL語句 ...
  • 當我們在linux上, 使用yum 安裝包時,報錯如下: 這時我們需要安裝EPEL EPEL,即Extra Packages for Enterprise Linux,這個軟體倉庫里有很多非常常用的軟體,而且是專門針對RHEL設計的,對RHEL標準yum源是一個很好的補充,完全免費使用,由Fedor ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...