天天看點

快速搭建Web Api OData V4服務端

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。

快速搭建Web Api OData V4服務端

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控制器

快速搭建Web Api OData V4服務端
快速搭建Web Api OData V4服務端

然後運作項目,浏覽http://localhost:54611/odata,驗證OData V3服務端可以通路。

快速搭建Web Api OData V4服務端

2.更新到OData V4服務端

NuGet下載下傳Microsoft.AspNet.Odata。注意,6.0是不行的,5.10.0可以,其他版本我沒有一一測試。

快速搭建Web Api OData V4服務端

然後,打開BooksController控制器,把命名空間替換一下

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

再打開WebApiConfig,把命名空間替換一下

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

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

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

然後再次編譯項目,浏覽http://localhost:54611/odata,可以看到顯示内容已經變了,已經更新到OData V4

快速搭建Web Api 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,下載下傳安裝,網絡非常慢……

快速搭建Web Api OData V4服務端

重新開機VS2015,給項目添加OData Client檔案,取名為BookODataClient.tt

快速搭建Web Api OData V4服務端

忽略安全警告,系統自動建立了BookODataClient.tt,打開這個檔案,給public const string MetadataDocumentUri指派OData V4服務端路徑。

快速搭建Web Api OData V4服務端

把OData V4服務端運作起來,對BookODataClient.tt運作自定義工具

快速搭建Web Api OData V4服務端

然後,系統自動建立了一大堆代碼……

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(, , ), Author = "金庸", Price = f },
                new Book() { Name = "神雕俠侶", PublishDate = new DateTime(, , ), Author = "金庸", Price = f },
                new Book() { Name = "倚天屠龍記", PublishDate = new DateTime(, , ), Author = "金庸", Price = f },
                new Book() { Name = "小李飛刀", PublishDate = new DateTime(, , ), Author = "古龍", Price = f },
                new Book() { Name = "絕代雙驕", PublishDate = new DateTime(, , ), Author = "古龍", Price = f },
            };

            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 += ;
                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().Take().ToList();
        }
           
快速搭建Web Api OData V4服務端

為什麼要費這麼大勁把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>