OData - ASP.NET Web API 2 中Odata路由约定
来源:互联网 发布:数据迁移服务 编辑:程序博客网 时间:2024/06/05 05:45
原文地址:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-routing-conventions
本文介绍的是Web API中使用的odata endpoints 的路由约定。
术语
URI:统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对网络中(一般指万维网)的资源通过特定的协议进行交互操作。URI包括URL和URN。
当Web API得到一个OData请求,它会自动映射到相应的Controller和Action名字。这个映射是基于HTTP方法和URI的。例如:GET /odata/Products(1) 映射到ProductsController.GetProduct.
本文Part 1介绍的是内置的OData路由约定。这些路由约定是专门为OData endpoints设计的,并且他们覆盖了默认的Web API路由系统(当调用MapODataRoute时覆盖将会发生)。
本文Part 2介绍的是如何添加自定义的OData路由约定。目前内置的OData路由约定并没有覆盖到所有的OData URIs,但是你可以扩展他们来处理额外的案例。
内置路由约定
首先下面有些方便理解OData Uri的准备知识:
URI 组成: 服务器根service root,资源路径resource path,查询选项Query options。
针对路由,最重要的部分是Resource Path。Resource Path被分成片段。例如上面的URI例子"Products(1)/Supplier"有三个片段:
- Products: 代表名为Products的entity set。
- 1:表示entity的主键,从entity set中短暂单个entity。
- Supplier:属于导航属性(navigation property),选择相关联entity。
所以上面的例子查询结果:product 1的Supplier。
Controller Name
Controller Name 通常都是衍生于Resource Path根部的entity set。继续上面的例子“Products(1)/Supplier”:Web API查找名为ProductsController的controller。
Action Name
Action Name通常衍生于路径片段加上实体数据模型(EDM: Entity Data Model),如下表中所示。有时候,你有两种Action Name选择,如"Get"和“GetProduct”。
查询entities
请求类型
URI例子
操作名字(Action)
Action例子
GET /entityset
/Products
GetEntitySet or Get
GetProducts
GET /entityset(key)
/Products(1)
GetEntityType or Get
GetProduct
GET /entityset(key)/cast
/Products(1)/Models.Book
GetEntityType or Get
GetBook
更多的资料查看:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v3/creating-an-odata-endpoint(OData V3)
增、删、改entities
URI例子
操作名字(Action)
Action例子POST /entityset(增)
/Products
PostEntityType or Post
PostProduct
PUT /entityset(key)(改)/Products(1)
PutEntityType or Put
PutProduct
PUT /entityset(key)/cast(改)
/Products(1)/Models.Book
PutEntityType or Put
PutBook
PATCH /entityset(key)(改)
/Products(1)
PatchEntityType or Patch
PatchProduct
PATCH /entityset(key)/cast(改)
/Products(1)/Models.Book
PatchEntityType or Patch
PatchBook
DELETE /entityset(key)(删)
/Products(1)
DeleteEntityType or Delete
DeleteProduct
DELETE /entityset(key)/cast(删)
/Products(1)/Models.Book
DeleteEntityType or Delete
DeleteBook
查询导航属性( Navigation Property)
请求类型
URI例子
Action Name
Action例子
GET /entityset(key)/navigation
/Products(1)/Supplier
GetNavigationFromEntityType or GetNavigation
GetSupplierFromProduct
GET /entityset(key)/cast/navigation
/Products(1)/Models.Book/Author
GetNavigationFromEntityType or GetNavigation
GetAuthorFromBook
更多信息查看:Working with Entity Relations.
增、删entities之间的联系(links)
请求类型
URI例子
Action Name
POST /entityset(key)/$links/navigation
/Products(1)/$links/Supplier
CreateLink
PUT /entityset(key)/$links/navigation
/Products(1)/$links/Supplier
CreateLink
DELETE /entityset(key)/$links/navigation
/Products(1)/$links/Supplier
DeleteLink
DELETE /entityset(key)/$links/navigation(relatedKey)
/Products/(1)/$links/Suppliers(1)
DeleteLink
更多信息查看:Working with Entity Relations.
属性properties(需要Web API 2)
请求类型
URI例子
Action Name
Action例子
GET /entityset(key)/property
/Products(1)/Name
GetPropertyFromEntityType or GetProperty
GetTitleFromBook
GET /entityset(key)/cast/property
/Products(1)/Models.Book/Author
GetPropertyFromEntityType or GetProperty
GetTitleFromBook
操作Action
请求类型
URI例子
Action Name
Action例子
GET /entityset(key)/ action
/Products(1)/Rate
ActionNameOnEntityType or ActionName
RateOnProduct
GET /entityset(key)/cast/ action
/Products(1)/Models.Book/CheckOut
ActionNameOnEntityType or ActionName
CheckOutOnBook
更多信息查看:OData Actions.
方法签名(Action Signatures)
这里有方法签名的几个规则:
- 如果路径中包括主键,action中必须有一个以主键为名的参数。
- 如果路径中包括导航属性中的主键(即关系entity的外键),action中必须有一个以外键为名的参数。
- 用[FromODataUri]参数来修饰主键和外键参数。
- POST 和PUT 请求需要有entity中的一个参数。
- PATCH请求需要Delta类型参数,其中T是entity类型
下面是每个内置Odatal路由约定的方法签名的例子:
public class ProductsController : ODataController{ // GET /odata/Products public IQueryable<Product> Get() // GET /odata/Products(1) public Product Get([FromODataUri] int key) // GET /odata/Products(1)/ODataRouting.Models.Book public Book GetBook([FromODataUri] int key) // POST /odata/Products public HttpResponseMessage Post(Product item) // PUT /odata/Products(1) public HttpResponseMessage Put([FromODataUri] int key, Product item) // PATCH /odata/Products(1) public HttpResponseMessage Patch([FromODataUri] int key, Delta<Product> item) // DELETE /odata/Products(1) public HttpResponseMessage Delete([FromODataUri] int key) // PUT /odata/Products(1)/ODataRouting.Models.Book public HttpResponseMessage PutBook([FromODataUri] int key, Book item) // PATCH /odata/Products(1)/ODataRouting.Models.Book public HttpResponseMessage PatchBook([FromODataUri] int key, Delta<Book> item) // DELETE /odata/Products(1)/ODataRouting.Models.Book public HttpResponseMessage DeleteBook([FromODataUri] int key) // GET /odata/Products(1)/Supplier public Supplier GetSupplierFromProduct([FromODataUri] int key) // GET /odata/Products(1)/ODataRouting.Models.Book/Author public Author GetAuthorFromBook([FromODataUri] int key) // POST /odata/Products(1)/$links/Supplier public HttpResponseMessage CreateLink([FromODataUri] int key, string navigationProperty, [FromBody] Uri link) // DELETE /odata/Products(1)/$links/Supplier public HttpResponseMessage DeleteLink([FromODataUri] int key, string navigationProperty, [FromBody] Uri link) // DELETE /odata/Products(1)/$links/Parts(1) public HttpResponseMessage DeleteLink([FromODataUri] int key, string relatedKey, string navigationProperty) // GET odata/Products(1)/Name // GET odata/Products(1)/Name/$value public HttpResponseMessage GetNameFromProduct([FromODataUri] int key) // GET /odata/Products(1)/ODataRouting.Models.Book/Title // GET /odata/Products(1)/ODataRouting.Models.Book/Title/$value public HttpResponseMessage GetTitleFromBook([FromODataUri] int key)}
自定义路由约定
可以通过实现IODataRoutingConvention接口来自定义路由约定,以添加其他可能OData URIs。该接口有两个方法:
string SelectController(ODataPath odataPath, HttpRequestMessage request);//返回Controller名字string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap);//返回Action名字
两个方法,当该约定不应用于某个请求,则都是返回null。
直接给出一个例子吧:/odata/Products(1)/Suppliers(1)
以下是自定义约定来实现的query。
using System.Web.OData.Routing;using System.Web.OData.Routing.Conventions;using System.Linq;using System.Net.Http;using System.Web.Http.Controllers;using Microsoft.OData.Edm;namespace ODataRouting{ public class NavigationIndexRoutingConvention : EntitySetRoutingConvention { //返回Action名字 public override string SelectAction(ODataPath odataPath, HttpControllerContext context, ILookup<string, HttpActionDescriptor> actionMap) { if (context.Request.Method == HttpMethod.Get && odataPath.PathTemplate == "~/entityset/key/navigation/key") { NavigationPathSegment navigationSegment = odataPath.Segments[2] as NavigationPathSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty.Partner; IEdmEntityType declaringType = navigationProperty.DeclaringType as IEdmEntityType; string actionName = "Get" + declaringType.Name; if (actionMap.Contains(actionName)) { // Add keys to route data, so they will bind to action parameters. KeyValuePathSegment keyValueSegment = odataPath.Segments[1] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.Key] = keyValueSegment.Value; KeyValuePathSegment relatedKeySegment = odataPath.Segments[3] as KeyValuePathSegment; context.RouteData.Values[ODataRouteConstants.RelatedKey] = relatedKeySegment.Value; return actionName; } } // Not a match. return null; } }}
要点:
- 派生于EntitySetRoutingConvention,因为在这个类中SelectController方法适用于新的路由约定,不需要重写SelectController。
- 这个约定只适用于Get请求,而且只有当路径模式是:“~/entityset/key/navigation/key”。
- action名字是“Get{EntityType}”,其中{EntityType}是导航属性集合中类型。如:GetSupplier。你可以使用任何命名约定,只要Controller名字匹配上。
- action有key和relatekey两个参数。(ODataRouteConstants.)
下一步将新约定加入到路由约定。(WebApiConfig.cs)
using ODataRouting.Models;using System.Web.Http;using System.Web.Http.OData.Builder;using System.Web.Http.OData.Routing;using System.Web.Http.OData.Routing.Conventions;namespace ODataRouting{ public static class WebApiConfig { public static void Register(HttpConfiguration config) { ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); // Create EDM (not shown). // Create the default collection of built-in conventions. var conventions = ODataRoutingConventions.CreateDefault(); // Insert the custom convention at the start of the collection. conventions.Insert(0, new NavigationIndexRoutingConvention()); config.Routes.MapODataRoute(routeName: "ODataRoute", routePrefix: "odata", model: modelBuilder.GetEdmModel(), pathHandler: new DefaultODataPathHandler(), routingConventions: conventions); } }}
其他有用相关例子:
- CompositeKeyRoutingConvention
- CustomNavigationRoutingConvention
- NonBindableActionRoutingConvention
- ODataVersionRouteConstraint
- source code
- OData - ASP.NET Web API 2 中Odata路由约定
- 在ASP.NET Web API中使用OData
- Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
- ASP.NET Web API对OData的支持
- Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2创建OData v4端点)
- ASP.NET Web API已支持OData v4.0,WCF不会
- OData
- 让Web API支持OData查询
- 快速搭建Web Api OData V4服务端
- OData v4 - Web API 轻量级应用(无Entity Framwork)
- VS2015 使用ODataV4创建Web Api和OData客户端
- OData demo 2
- ASP.NET Web API Selfhost宿主环境中管道、路由
- ASP.NET Web API WebHost宿主环境中管道、路由
- ASP.Net Web API 中基于属性的路由使用
- ASP.NET Web API 路由对象介绍
- 《Asp.Net Web Api 》-----路由机制
- OData v4 - Web API 轻量级应用(使用Entity Framwork)-Endpoint
- Lufylenged引擎学习——LLoader、LBitmap
- HDU 1241 Oil Deposits
- 枚举简单示例
- JS遍历list异常情况解决
- hdu 1495 非常可乐
- OData - ASP.NET Web API 2 中Odata路由约定
- IIS7 允许下载MDB文件 设置修改办法
- 24-IO流-69-IO流(联通问题)
- 【面试笔试-c/c++】兰亭集势2013校园招聘试题。
- spring注解( @Autowired、@Qualifier、@Resource、@PostConstruct、@PreDestroy、 @Component、@Scope)-描述的比较清楚
- [HDU 4081] Qin Shi Huang's National Road System 最小树
- Version和Build的区别
- 静态变量的初始化
- Linux启动管理器