快速搭建Web Api OData V4服务端

来源:互联网 发布:mac os 系统修复 编辑:程序博客网 时间:2024/06/08 06:32

VS2015可以自动化搭建Web Api OData V3服务端,但是不能自动化搭建OData V4服务端。微软官网给出了一个例程,https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint,可以手动编码搭建OData V4服务端。
经过试验,发现可以把OData V3服务端升级到OData V4,可以省很多事。以下为操作步骤。

1.自动化搭建OData V3服务端

新建Asp.NET空白项目,打勾Web API。
这里写图片描述

NuGet下载EF 6.1.3。

定义实体类,定义数据库。

public class Book    {        public int id { get; set; }        public string Name { get; set; }//书名        public DateTime PublishDate { get; set; }//出版日期        public string Author { get; set; }//作者        public float Price { get; set; }//价格    }    public class MyBookDB : DbContext    {        public DbSet<Book> Books { get; set; }        public MyBookDB() : base("dbConn")        {            Database.SetInitializer<MyBookDB>(new DropCreateDatabaseIfModelChanges<MyBookDB>());        }    }

编译项目,添加OData V3控制器
这里写图片描述
这里写图片描述

然后运行项目,浏览http://localhost:54611/odata,验证OData V3服务端可以访问。
这里写图片描述

2.升级到OData V4服务端

NuGet下载Microsoft.AspNet.Odata。注意,6.0是不行的,5.10.0可以,其他版本我没有一一测试。
这里写图片描述

然后,打开BooksController控制器,把命名空间替换一下

//using System.Web.Http.OData;//OData V3using System.Web.OData;//OData V4

再打开WebApiConfig,把命名空间替换一下

//using System.Web.Http.OData.Builder;//OData V3//using System.Web.Http.OData.Extensions;//OData V3using System.Web.OData.Builder;//OData V4using System.Web.OData.Extensions;//OData V4

配置OData路由的函数小改一下

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();builder.EntitySet<Book>("Books");//config.Routes.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());//OData V3config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());//OData V4

然后再次编译项目,浏览http://localhost:54611/odata,可以看到显示内容已经变了,已经升级到OData V4
这里写图片描述

3.创建OData客户端

参考https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-client-app
新建一个Winform项目,在扩展和更新工具里搜索OData Client Code Generator,下载安装,网络非常慢……
这里写图片描述

重启VS2015,给项目添加OData Client文件,取名为BookODataClient.tt
这里写图片描述

忽略安全警告,系统自动创建了BookODataClient.tt,打开这个文件,给public const string MetadataDocumentUri赋值OData V4服务端路径。
这里写图片描述

把OData V4服务端运行起来,对BookODataClient.tt运行自定义工具
这里写图片描述

然后,系统自动创建了一大堆代码……

4.测试OData功能

然后就可以对数据库增删改查了。

        private string serviceUri;        private Default.Container container;        private void Form1_Load(object sender, EventArgs e)        {            serviceUri = "http://localhost:54611/odata";            container = new Default.Container(new Uri(serviceUri));        }        private void btnAdd_Click(object sender, EventArgs e)        {            List<Book> books = new List<Book>()            {                new Book() { Name = "射雕英雄传", PublishDate = new DateTime(1960, 1, 1), Author = "金庸", Price = 10.5f },                new Book() { Name = "神雕侠侣", PublishDate = new DateTime(1960, 2, 2), Author = "金庸", Price = 12.5f },                new Book() { Name = "倚天屠龙记", PublishDate = new DateTime(1960, 3, 3), Author = "金庸", Price = 16.5f },                new Book() { Name = "小李飞刀", PublishDate = new DateTime(1965, 5, 5), Author = "古龙", Price = 13.5f },                new Book() { Name = "绝代双骄", PublishDate = new DateTime(1965, 6, 6), Author = "古龙", Price = 15.5f },            };            foreach (Book book in books)            {                container.AddToBooks(book);            }            var serviceResponse = container.SaveChanges();            foreach (var operationResponse in serviceResponse)            {                //返回多个结果201               Debug.Print("Response: {0}", operationResponse.StatusCode);            }        }        private void btnModify_Click(object sender, EventArgs e)        {            var book = container.Books.Where(x => x.Name == "绝代双骄").FirstOrDefault();            if (book != null)            {                book.Price += 1;                container.UpdateObject(book);                var serviceResponse = container.SaveChanges();                foreach (var operationResponse in serviceResponse)                {                    //没有返回结果                    Debug.Print("Response: {0}", operationResponse.StatusCode);                }            }        }        private void btnDel_Click(object sender, EventArgs e)        {            var book = container.Books.Where(x => x.Name == "绝代双骄").FirstOrDefault();            if (book != null)            {                container.DeleteObject(book);                var serviceResponse = container.SaveChanges();                foreach (var operationResponse in serviceResponse)                {                    //返回结果204                    Debug.Print("Response: {0}", operationResponse.StatusCode);                }            }        }        private void btnQuery_Click(object sender, EventArgs e)        {            //ToList()才获取查询结果            this.dataGridView1.DataSource = container.Books.Where(x => x.Author == "金庸").OrderByDescending(x => x.PublishDate).ToList();        }        private void btnRefresh_Click(object sender, EventArgs e)        {            //ToList()才获取查询结果            //服务端分页            this.dataGridView1.DataSource = container.Books.OrderByDescending(x => x.Price).Skip(2).Take(2).ToList();        }

这里写图片描述

为什么要费这么大劲把OData V3升级到V4?当然不是蛋疼,而是因为V4支持获取数据库记录:int count = container.Books.Count();

可以把OData V4服务端部署到IIS,用Fiddler抓包,查看每次发送和收到的原始数据。
注意:部署OData V4服务端到IIS的时候,要修改Web.config,支持DELETE谓词

<system.webServer>    <modules>      <!--允许DELETE谓词-->      <remove name="WebDAVModule" />    </modules><handlers>      <!--允许DELETE谓词-->      <remove name="WebDAV" />      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />      <remove name="OPTIONSVerbHandler" />      <remove name="TRACEVerbHandler" />      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />    </handlers>  </system.webServer>