[水煮 ASP.NET Web API2 方法论](12-2)管理 OData 路由
2016-11-21 08:45
465 查看
问题
如何控制 OData 路由
解决方案
为了注册路由,可以使用 HttpConfigurationExtension 类中 MapODataServiceRoute 的扩展方法。对于单一路由这样做足以,其余的处理由实体数据模型来处理。
从 ASP.NET Web API 2.2 开始支持 OData 直接声明路由,在 Action 上使用 ODataRouteAttribute。这和常规的属性路由一样,可以通过 ODataRoutePrefixAttribute 在 Controller 级别设置路由前缀.
工作原理
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 定义
当我们定义 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 被包含。
结果就是,在应用程序启动,不在需要调用任何其他的方法通知框架扫描所有的路由属性。事实上,只有这样,才能在最开始的地方获取属性路由并调用 MapODataServiceRoute.
代码演示
为了介绍 OData Web API 的集中路由,我们只需要在 HttpConfiguration 中调用 MapODataServiceRoute 和传路由前缀,以及我们的 IEdmModel。一个完整的启动类列子,使用简单的 OData 实体和集中路由,如清单 12-5 所示,使用 Player 实体。
清单 12-5. 声明一个基本的 OData 路由启动类
允许我们使用所有默认的内建路由约定,例如,
• 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 使用属性路由的例子
如何控制 OData 路由
解决方案
为了注册路由,可以使用 HttpConfigurationExtension 类中 MapODataServiceRoute 的扩展方法。对于单一路由这样做足以,其余的处理由实体数据模型来处理。
config.MapODataServiceRoute("OData", "OData", builder.GetEdmModel());
从 ASP.NET Web API 2.2 开始支持 OData 直接声明路由,在 Action 上使用 ODataRouteAttribute。这和常规的属性路由一样,可以通过 ODataRoutePrefixAttribute 在 Controller 级别设置路由前缀.
[ODataRoute("Players")] public IQueryable<Player> GetAllPlayers() { // 忽略 }
工作原理
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 定义
public interface IODataRoutingConvention { string SelectController(ODataPath ODataPath, HttpRequestMessage request); string SelectAction(ODataPath ODataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap); }
当我们定义 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 被包含。
public static class ODataRoutingConventions { public static IList<IODataRoutingConvention> CreateDefaultWithAttributeRouting( HttpConfiguration configuration, IEdmModel model) { if (configuration == null) { throw Error.ArgumentNull("configuration"); } if (model == null) { throw Error.ArgumentNull("model"); } IList<IODataRoutingConvention> routingConventions = CreateDefault(); AttributeRoutingConvention routingConvention = new AttributeRoutingConvention(model, configuration); routingConventions.Insert(0, routingConvention); return routingConventions; } public static IList<IODataRoutingConvention> CreateDefault() { return new List<IODataRoutingConvention>() { new MetadataRoutingConvention(), new EntitySetRoutingConvention(), new SingletonRoutingConvention(), new EntityRoutingConvention(), new NavigationRoutingConvention(), new PropertyRoutingConvention(), new RefRoutingConvention(), new ActionRoutingConvention(), new FunctionRoutingConvention(), new UnmappedRequestRoutingConvention() }; } }
结果就是,在应用程序启动,不在需要调用任何其他的方法通知框架扫描所有的路由属性。事实上,只有这样,才能在最开始的地方获取属性路由并调用 MapODataServiceRoute.
代码演示
为了介绍 OData Web API 的集中路由,我们只需要在 HttpConfiguration 中调用 MapODataServiceRoute 和传路由前缀,以及我们的 IEdmModel。一个完整的启动类列子,使用简单的 OData 实体和集中路由,如清单 12-5 所示,使用 Player 实体。
清单 12-5. 声明一个基本的 OData 路由启动类
public class Startup { public void Configuration(IAppBuilder builder) { var ODataBuilder = new ODataConventionModelBuilder(); ODataBuilder.EntitySet<Player>("Players"); var edm = ODataBuilder.GetEdmModel(); var config = new HttpConfiguration(); config.MapODataServiceRoute("Default OData", "OData", edm); builder.UseWebApi(config); } } public class Player { public int Id { get; set; } public string Name { get; set; } public string Team { get; set; } }
允许我们使用所有默认的内建路由约定,例如,
• 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 使用属性路由的例子
[ODataRoutePrefix("Players")] public class PlayersController : ODataController { private readonly PlayersContext _players = new PlayersContext(); [EnableQuery] [ODataRoute] public IQueryable<Player> GetAllPlayers() { return _players.AsQueryable(); } [EnableQuery] [ODataRoute("({key})")] public SingleResult<Player> GetSinglePlayers(int key) { return SingleResult.Create(_players.Where(x => x.Id == key).AsQueryable()); } }
相关文章推荐
- [水煮 ASP.NET Web API2 方法论](12-4)OData 支持的 Function 和 Action
- [水煮 ASP.NET Web API2 方法论](12-3)OData 查询
- [水煮 ASP.NET Web API2 方法论](12-1)创建 OData
- [水煮 ASP.NET Web API2 方法论](12-1)创建 OData
- [水煮 ASP.NET Web API2 方法论](3-2)直接式路由/属性路由
- [水煮 ASP.NET Web API2 方法论](3-6)万能路由
- [水煮 ASP.NET Web API2 方法论](3-9)空气路由的设置
- [水煮 ASP.NET Web API2 方法论](3-5)路由约束
- [水煮 ASP.NET Web API2 方法论](3-3)路由默认值
- [水煮 ASP.NET Web API2 方法论](3-4)设置路由可选项
- [水煮 ASP.NET Web API2 方法论](3-1)集中式路由
- [水煮 ASP.NET Web API2 方法论](3-8)怎样给指定路由配置处理器
- [水煮 ASP.NET Web API2 方法论](1-8)添加 Session 状态
- [水煮 ASP.NET Web API2 方法论](1-1)在MVC 应用程序中添加 ASP.NET Web API
- [水煮 ASP.NET Web API2 方法论](1-6)Model Validation
- [水煮 ASP.NET Web API2 方法论](3-7)默认 Action 请求方式以及 NonActionAttribute
- [水煮 ASP.NET Web API2 方法论](1-5)ASP.NET Web API Scaffolding(模板)
- [水煮 ASP.NET Web API2 方法论](1-3)如何接收 HTML 表单请求
- [水煮 ASP.NET Web API2 方法论](1-2)在 WebForm 应用程序中添加 ASP.NET Web API
- [水煮 ASP.NET Web API2 方法论](1-8)添加 Session 状态