[转]ASP.NET Web API对OData的支持

http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.html

在SOA的世界中,最重要的一个概念就是契约(contract)。在云计算的世界中,有关通信的最重要的概念也是契约。XML具有强大对数据的描述能力,Atom格式和AtomPub都建立在XML之上,在Google和微软的推动下,也已经成为标准。但是,Atom/AtomPub和ODBC/OLEDB这样的真正数据交互协议相比较,还有着根本上的欠缺:缺乏数据类型的具体描述,降低了交互性能。缺乏对数据查询的控制能力,比如返回特定的数据集合的区间,或者说分页能力等等。微软基于EDM模型释出了:OData,这里也可以看出Entity Framework对于NHibernate这样的ORM的工具不同的战略考虑。

在.NET中,早期是用Remoting/Webservice来处理所有程序间的通信,从.NET 3.0开始使用WCF统一了通信模型,ASP.NET MVC4的推出,形成大的One ASP.NET战略,增加了WebAPI和SingalR作为通信服务:

开放数据协议(OData)是一个查询和更新数据的Web协议。OData应用了web技术如HTTP、Atom发布协议(AtomPub)和JSON等来提供对不同应用程序,服务和存储的信息访问。除了提供一些基本的操作(像增删改查),也提供了一些高级的操作类似过滤数据和实体的导航。OData扩展了上述的协议但是不是取代他们。他可以被XML(ATOM)或者JSON取代但是OData的重要在于它符合REST原则。在某种意义上,它建立在‘简单‘的REST HTTP 服务上,并且有着清晰的目标——简化和标准化我们操作和查询数据的方式。如果你过去在给你的REST服务创建搜索、过滤、或者分页API的时候感觉很麻烦,那么OData将是一个不错的选择。

目前很多接口,无论是基于SOAP、REST还是别的都在交换数据时使用不同的模式。这种方法随后返回一大堆客户记录。你随后可以决定添加分页支持。你希望将结果捆绑在一个网格中,并对数据排序。最后,决定想要查询的东西,通过比如邮政编码来查询。

  首先是,没有创建泛型客户端的途径,而这些和API紧密联系,因为它不知道参数的顺序或者模式被使用的顺序。因为不能创建泛型客户端,你必须为每一个你希望暴露的API创建客户端。简单的基础HTTP API可以实现,但其仍旧很昂贵。逐渐增多的多样性客户端与这些API通信加剧了这个问题。

  这种模式的第二个问题是它迫使开发人员进行很艰难的权衡。我应该暴露多少个查询?你必要在暴露每一个你能想到内容和少暴露一些,从而削弱服务之间协调。前者导致API 需要管理的界面的增加,后者会导致我们通常所说的“数据竖井”,也就是关键数据在特定模式中锁定,其他应用不能够简单应用,因为它没有以一种需要的方式暴露给这个应用。服务试图比单一应用要获得更长久一些,因此你需要以一种方式设计API,使其能够持久,所以如果你发现你需要添加服务借口的新版本可不太好办,比如创建新的客户端。在很多案例中,服务开发者和客户端开发者并不是同一个人,因而改变服务接口简直就是不可能的事情。

  通过OData,我们采取不同的方法。取代创建客户端签名和参数,我们问了如下的问题:“如果你将数据集作为源处理,并为最频繁使用的操作定义模式,像查询、分页、排序、新建、删除和更新,服务接口因该是什么样子的?” 这也就导致OData的创建。OData解决了上面提到的关键服务设计挑战。

我们来看一下启用OData协议的WebAPI的例子:

http://localhost:8080/api/meetings

http://localhost:8080/api/meetings?$filter=(Leader eq ‘Mark Nichols’)

http://localhost:8080/api/meetings?$top=2

http://localhost:8080/api/meetings?$filter=MeetingDate eq datetime’2013-01-17′

在项目中启用OData查询,首先在项目加入Web API的OData支持,通过Nuget 查找ASP.NET Web API OData

Microsoft.AspNet.WebApi.OData提供可一系列的类扩展了Web API。

在项目中启用OData查询:

public static void Register(HttpConfiguration config) {     // ...     config.EnableQuerySupport();     // ... }

如果是使用self-hosting方式,在HttpSelfHostConfiguration上启用EnableQuerySupport():

var config = new HttpSelfHostConfiguration(new Uri("http://localhost:8080")); config.EnableQuerySupport();

然后将Controls上的Action的返回结果更改为IQueryable,并打上标签[Queryable()]:

        // GET api/Meeting
        [Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
        public IQueryable<Meeting> Get()
        {
            return _scheduledMeetings.AsQueryable();
        }
需要添加 using System.Web.Http.OData.Query; 我们下AllowedQueryOptions 看支持那些OData的类型:
   // Summary:
    //     OData query options to allow for querying.
    [Flags]
    public enum AllowedQueryOptions
    {
        // Summary:
        //     A value that corresponds to allowing no query options.
        None = 0,
        //
        // Summary:
        //     A value that corresponds to allowing the $filter query option.
        Filter = 1,
        //
        // Summary:
        //     A value that corresponds to allowing the $expand query option.
        Expand = 2,
        //
        // Summary:
        //     A value that corresponds to allowing the $select query option.
        Select = 4,
        //
        // Summary:
        //     A value that corresponds to allowing the $orderby query option.
        OrderBy = 8,
        //
        // Summary:
        //     A value that corresponds to allowing the $top query option.
        Top = 16,
        //
        // Summary:
        //     A value that corresponds to allowing the $skip query option.
        Skip = 32,
        //
        // Summary:
        //     A value that corresponds to allowing the $inlinecount query option.
        InlineCount = 64,
        //
        // Summary:
        //     A value that corresponds to the default query options supported by System.Web.Http.QueryableAttribute.
        Supported = 121,
        //
        // Summary:
        //     A value that corresponds to allowing the $format query option.
        Format = 128,
        //
        // Summary:
        //     A value that corresponds to allowing the $skiptoken query option.
        SkipToken = 256,
        //
        // Summary:
        //     A value that corresponds to allowing all query options.
        All = 511,
    }

上面有个Format,我们可以进行格式化输出。使用下面的代码对Format进行数据格式化:

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
           

config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json"); config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");

            config.EnableQuerySupport();
        }

另外需要注意的一点是OData查询是大小写敏感的。

我将使用Fiddler去测试这个服务

我们没有写任何一个特别的逻辑去支持这些功能,全部都由框架来提供的。是不是OData为你的搜索、过滤、或者分页API的时候提供了一个很好的选项。

然而,如果要向组织外部公开可查询的操作,可以利用查询验证添加一个保护层以保护我们的服务。微软的程序经理Hongmei Ge介绍了几种在Queryable API中添加验证的场景。

Hongmei指出的第一个场景是,使用AllowedQueryOptions属性,只允许包含$top和$skip的查询。如下所示:

[Queryable(AllowedQueryOptions = AllowedQueryOptions.Skip | AllowedQueryOptions.Top)] public IQueryable Get(int projectId)

还可以使用MaxTop和MaxSkip属性将$top和$skip的最大值限制在100和200:

[Queryable(MaxTop = 100)] public IQueryable Get(int projectId)

[Queryable(MaxSkip = 200)] public IQueryable Get(int projectId)

利用AllowedOrderByProperties,可以将结果按Id属性排序,因为按其他属性排序可能会很慢:

[Queryable(AllowedOrderByProperties = "Id")] public IQueryable Get(int projectId)

如果允许客户端在$filter内使用相等比较,应该使用AllowedLogicalOperators对其进行验证:

[Queryable(AllowedLogicalOperators = AllowedLogicalOperators.Equal)] public IQueryable Get(int projectId)

将AllowedArithmeticOperators设置为None,就可以关闭$filter中的算术操作:

[Queryable(AllowedArithmeticOperators = AllowedArithmeticOperators.None)] public IQueryable Get(int projectId)

你还可以使用AllowedFunctions属性来限制$filter中的函数使用:

[Queryable(AllowedFunctions = AllowedFunctions.StartsWith)] public IQueryable Get(int projectId)

上面的代码意味着只能在$filter中使用StartsWith函数。

Hongmei还演示了高级场景中的查询验证,如为$skip、$top、$orderby、$filter自定义默认验证逻辑,以及使用ODataQueryOptions来验证查询。

相关文章:

OData Developers Reference: http://www.odata.org/developers/

OData in ASP.NET: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api

Limiting OData Query Options: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

OData Security: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-security-guidance

Add an OData Feed to Your App Using Web API:http://marknic.net/2013/03/02/add-an-odata-feed-to-your-app-using-web-api/

Working with OData Queries in ASP.NET Web API:http://www.codeguru.com/csharp/.net/working-with-odata-queries-in-asp.net-web-api.htm

在ASP.NET Web API OData中利用Queryable API进行验证: http://www.infoq.com/cn/news/2013/02/queryable-api

一个创建 OData 的新选项: Web API:http://msdn.microsoft.com/zh-cn/magazine/dn201742.aspx

Building OData Service using ASP.Net Web API Tutorial – Part 1

示例代码下载: http://files.cnblogs.com/shanyou/WebApiOData.zip

时间: 2024-08-09 07:43:47

[转]ASP.NET Web API对OData的支持的相关文章

ASP.NET Web API对OData的支持

小分享:我有几张阿里云优惠券,用券购买或者升级阿里云相应产品最多可以优惠五折!领券地址:https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=ohmepe03 在SOA的世界中,最重要的一个概念就是契约(contract).在云计算的世界中,有关通信的最重要的概念也是契约.XML具有强大对数据的描述能力,Atom格式和AtomPub都建立在XML之上,在Google和微软的推动下,也已经成为标准.但是

ASP.NET Web API基于OData的增删改查,以及处理实体间关系

本篇体验实现ASP.NET Web API基于OData的增删改查,以及处理实体间的关系. 首先是比较典型的一对多关系,Supplier和Product. public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public string Category { get; set; } [ForeignKey("Sup

[转]ASP.NET web API 2 OData enhancements

本文转自:https://www.pluralsight.com/blog/tutorials/asp-net-web-api-2-odata-enhancements Along with the release of Visual Studio 2013 came a new release of ASP.NET MVC (called MVC 5) and ASP.NET Web API (called Web API 2). Part of the enhancements to the

如何让你的 Asp.Net Web Api 接口,拥抱支持跨域访问。

由于 web api 项目通常是被做成了一个独立站点,来提供数据,在做web api 项目的时候,不免前端会遇到跨域访问接口的问题. 刚开始没做任何处理,用jsonp的方式调用 web api 接口,总是报一个错误,如下: 如果你想用JSONP来获得跨域的数据,WebAPI本身是不支持javascript的callback的,它返回的JSON是这样的: {"YourSignature":"嫁人要嫁程序员,钱多话少死得早"} 然而,JSONP请求期望得到这样的JSON

XPO - Web API and OData V4 支持

XPO - Web API and OData V4 支持: https://community.devexpress.com/blogs/xpo/archive/2018/07/05/xpo-web-api-and-odata-v4-support.aspx https://community.devexpress.com/blogs/xpo/archive/2018/05/21/xpo-free-of-charge-in-v18-1.aspx 原文地址:https://www.cnblogs

[转]Using $select, $expand, and $value in ASP.NET Web API 2 OData

本文转自:https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/using-select-expand-and-value by Mike Wasson+ Web API 2 adds support for the $expand, $select, and $value options in OData. These options allow a client to

asp.net web api 使用Odata

路由配置 routePrefix路由前缀,必须含有Odata字符串,否则路由不到Odata控制器. V1表示版本,可以使用这种方式进行版本控制,也可以使用其他方式. config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);这样配置使Odata操作符可用(Web Api2的旧版本不必如此设置). public static class WebApiConfig { public static void Register(Ht

对一个前端AngularJS,后端OData,ASP.NET Web API案例的理解

依然chsakell,他写了一篇前端AngularJS,后端OData,ASP.NET Web API的Demo,关于OData在ASP.NET Web API中的正删改查没有什么特别之处,但在前端调用API时,把各种调用使用$resouce封装在一个服务中的写法颇有借鉴意义. 文章:http://chsakell.com/2015/04/04/asp-net-web-api-feat-odata/源码:https://github.com/chsakell/odatawebapi 首先是领域模

ASP.NET Web API系列教程(目录)(转)

注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内对此关注的人似乎还不多,有关ASP.NET Web API的文章也不多见.为此,本人打算对微软ASP.NET Web API官方网站上的一些教程进行翻译,以期让更多的国人了解.学习和使用这项ASP.NET Web API. ASP.NET Web API系列教程目录 Introduction:Wha