本文共 8670 字,大约阅读时间需要 28 分钟。
还是看的简单说明:
An open protocol to allow the creation and consumption of queryable and interoperable RESTful APIs in a simple and standard way.
这是一个开放的数据查询和服务协议,目前已经有众多厂商和平台支持,已经形成了完整的生态链,这应该是未来数据查询的标准,。
OData的意义还在于,它能够大大简小SOA架构里面服务的粒度,只需要提供一个OData数据源,而查询工作交给客户端去做即可,这将大大减少服务端服务方法定义的数量。
OData的版本现在已经是V4了,之前的很多类库都是基于V1-V3版本的。现在的V4版本已经很完善了,而且成为了工业标准,所以现在可以放心的在项目中使用了。
OData 的前身是WCF Data Service,后来演变成跨平台的数据查询协议,现在,除了WCF支持OData,ASP.NET WebAPI 已经内置支持OData了,这将获得一种轻量级的,Rest架构的OData访问方案,本文将讲解如何在VS 2013上搭建一个OData 服务和客户端程序。
在阅读本文之前,首先建议你参考下面的OData 学习资源,本文也是根据这里的资源整理而成,之所以要重新整理一次,是因为原文说的并不清楚,给出的示例程序有些小小的问题,而且国内有关OData的文章介绍非常少。
本文的实例程序相关代码
新建一个ASP.NET WebAPI 项目,名字是 ODataWebApplication ,如下图:
注意选择一个空项目,并购选WebAPI,单击确定。
打开VS2013的程序包管理器控制台,在下面输入 Install-Package Microsoft.AspNet.OData 命令,如下图:
这里会添加很多附属的程序集文件,下面是一个详细的清单列表,如果你的符合下面的内容,就表示安装成功了:
按照 这个链接内容的文章,添加Model和控制器,具体过程请参考原文。在本篇文章的实例中,为了更好的重用Model,我将它放到了一个独立的Demo.Models 项目中。
注意,添加控制器的时候选择空的 WebAPI 控制器,不要选择带OData 的。
下面是添加完整后的项目目录结构:
立刻运行这个项目,发现报下面的错误:
未能加载文件或程序集“System.Web.Http, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
此时需要在Web.config 文件中加入下面的配置内容:
也可以在编译项目的时候,注意查看“输出窗口”,单击“警告”的文字内容,会有下面的提示询问,回答确定即可自动为你添加上面的内容:
再次运行,程序不报错了,用谷歌浏览器来打开本程序,出现了下面的内容,就表示ASP.NET WebAPI OData V4 已经成功了:
{ "@odata.context":"http://localhost:20491/$metadata#People","value":[ { "ID":"001","Name":"Angel","Description":null },{ "ID":"002","Name":"Clyde","Description":"Contrary to popular belief, Lorem Ipsum is not simply random text." },{ "ID":"003","Name":"Elaine","Description":"It has roots in a piece of classical Latin literature from 45 BC, making Lorems over 2000 years old." } ]}
按照下面链接文章的内容,新建一个控制台程序:
按照上面链接文章的内容,添加此工具,如下图:
下载好该工具后让你安装运行,最后会让你重启动VS。
重新启动后,如果看到下面的内容,表示该工具安装成功了。
该工具运行后,会在项目下面添加一个OData Client T4 文件,添加后,运行该项目,会报下面的错误:
错误 1 正在运行转换: System.ArgumentException: The value "" is not a valid MetadataDocumentUri because is it not a valid absolute Uri. The MetadataDocumentUri must be set to an absolute Uri referencing the $metadata endpoint of an OData service. 在 Microsoft.VisualStudio.TextTemplating0CFD4DFE54AE767D51F4D19A4964CA0B33E6E87CF53FFF790646D6E3F14916C4544A62E4C781ABB55BC19EE5225FDBA7E28D9767E56040F8F9A9EF5278D6B7CA.GeneratedTextTransformation.set_MetadataDocumentUri(String value) 位置 c:\Users\dth\Documents\Visual Studio 2013\Projects\ODataWebApplication\Demo.ConsoleClient\ODataClient1.ttinclude:行号 125 在 Microsoft.VisualStudio.TextTemplating0CFD4DFE54AE767D51F4D19A4964CA0B33E6E87CF53FFF790646D6E3F14916C4544A62E4C781ABB55BC19EE5225FDBA7E28D9767E56040F8F9A9EF5278D6B7CA.GeneratedTextTransformation.ApplyParametersFromConfigurationClass() 位置 c:\Users\dth\Documents\Visual Studio 2013\Projects\ODataWebApplication\Demo.ConsoleClient\ODataClient1.ttinclude:行号 313 在 Microsoft.VisualStudio.TextTemplating0CFD4DFE54AE767D51F4D19A4964CA0B33E6E87CF53FFF790646D6E3F14916C4544A62E4C781ABB55BC19EE5225FDBA7E28D9767E56040F8F9A9EF5278D6B7CA.GeneratedTextTransformation.TransformText() 位置 c:\Users\dth\Documents\Visual Studio 2013\Projects\ODataWebApplication\Demo.ConsoleClient\ODataClient1.ttinclude:行号 58 c:\Users\dth\Documents\Visual Studio 2013\Projects\ODataWebApplication\Demo.ConsoleClient\ODataClient1.ttinclude 125 1 Demo.ConsoleClient
根据错误信息,找到T4文件错误的位置,将前面的OData WebAPI项目的地址,写在文件里面,如下所示:
// The URI of the metadata document. The value must be set to a valid service document URI or a local file path // eg : "http://services.odata.org/V4/OData/OData.svc/", "File:///C:/Odata.edmx", or @"C:\Odata.edmx" // ### Notice ### If the OData service requires authentication for accessing the metadata document, the value of // MetadataDocumentUri has to be set to a local file path, or the client code generation process will fail. public const string MetadataDocumentUri = "http://localhost:20491/";
此时再次运行该T4文件,我们发现OData Client 代理类文件生成了,内容很多,这里就不贴了。
添加下面的代码,调用OData Client 代理类并运行:
class Program { static void Main(string[] args) { // TODO: Replace with your local URI. string serviceUri = "http://localhost:20491/"; var container = new DefaultContainer(new Uri(serviceUri)); foreach (var p in container.People) { Console.WriteLine("{0} {1} {2}", p.ID, p.Name, p.Description); } Console.Read(); } }
如果看到下面的运行结果,表示OData Client 程序成功了:
至此,OData WebAPI Serivce & Client 的工作就全部完成了。
经过前面的过程我们看到,依托于OData 客户端工具生成OData 代理类的过程还是比较麻烦的,当然好处也有,但缺点就是没有手工操控的那么灵活自由。
仔细研究下前面的代理类,我们发现这里关键依赖于 Microsoft.OData.Client 程序集的DataServiceContext 对象,将代理类进行抽取封装就可以完成我们手工的代理类了。
创建一个类库项目,新建一个 ODataV4ContextBase.cs 文件,
接着为该项目添加Nuget 依赖的包:
Install-Package Microsoft.OData.Client
然后在项目下增加了一个文件 packages.config,里面有如下内容:
然后,编写ODataV4ContextBase 类的具体内容:
using Microsoft.OData.Client;using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace PWMIS.OData.Client{ ////// OData V4 Version ASP.NET WebAPI OData RestFull Client Context /// public class ODataV4ContextBase : DataServiceContext { ///v1.0 2015.4.1 http://www.pwmis.com/sqlmap ////// V4 OData Init /// /// V4 OData ASP.NET WebAPI url base public ODataV4ContextBase(string serviceRoot) : base(new System.Uri( serviceRoot), ODataProtocolVersion.V4) { if (!serviceRoot.EndsWith("/")) serviceRoot = serviceRoot + "/"; GeneratedEdmModel gem = new GeneratedEdmModel(serviceRoot); this.Format.LoadServiceModel = gem.GetEdmModel; this.Format.UseJson(); } public IQueryableCreateNewQuery (string name) where T : class { return base.CreateQuery (name); } class GeneratedEdmModel { private string ServiceRootUrl; public GeneratedEdmModel(string serviceRootUrl) { this.ServiceRootUrl = serviceRootUrl; } public Microsoft.OData.Edm.IEdmModel GetEdmModel() { string metadataUrl = ServiceRootUrl + "$metadata"; return LoadModelFromUrl(metadataUrl); } private Microsoft.OData.Edm.IEdmModel LoadModelFromUrl(string metadataUrl) { System.Xml.XmlReader reader = CreateXmlReaderFromUrl(metadataUrl); try { return Microsoft.OData.Edm.Csdl.EdmxReader.Parse(reader); } finally { ((System.IDisposable)(reader)).Dispose(); } } private static System.Xml.XmlReader CreateXmlReaderFromUrl(string inputUri) { return System.Xml.XmlReader.Create(inputUri); } } }}
在解决方案里面添加一个WinForm项目,在项目里面添加一个ODataContainer.cs 文件,内容如下:
class ODataContainer : PWMIS.OData.Client.ODataV4ContextBase { public ODataContainer(string serviceRoot):base(serviceRoot) { } public IQueryablePeople { get { return base.CreateNewQuery ("People"); } } }
非常的简单,这里只是添加了一个属性 People。
然后,在窗体代码中调用:
private void button1_Click(object sender, EventArgs e) { string serviceUri = "http://localhost:20491/"; var container = new ODataContainer(serviceUri); var query = container.People.Where(p => p.Description!=null); this.dataGridView1.DataSource = query.ToList(); }
最后运行该程序,出现下面的界面,就表示成功了:
至此,一个不依赖于EF的全内存的OData 应用程序就完全做好了,更多OData的研究,请大家一起来做吧。
感谢支持 框架,相关代码
注:本文说的 ODataV4ContextBase OData客户端基类程序已经集成到了PDF.NET框架中,在上面的下载里面即可看到。
本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/p/4384659.html,如需转载请自行联系原作者