天天看點

Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2建立OData v4端點)...

開放資料協定Open Data Protocol(OData)是web的一種資料存取協定,OData通過設定CRUD操作(Create建立。Read讀取。Update更新,Delete删除)提供一種統一的方式來查詢或者操作資料。

ASP.Net Web API同一時候支援該協定v3和v4版本号,你甚至能夠在執行v4的端點(Endpoint)時執行v3的端點(Endpoint)。

本課程展示了怎樣建立OData v4的端點(Endpoint)來提供CRUD操作。

教程裡使用的軟體版本号

    • Web API 2.2
    • OData v4
    • Visual Studio 2013 Update 2
    • Entity Framework 6
    • .NET 4.5

教程版本号

點選Creating an OData v3 Endpoint可跳轉至OData Version 3.

建立Visual Studioproject

打開Visual Studio,在File(檔案)菜單中。選擇New > Project(建立>項目)。

展開 Installed > Templates > Visual C# > Web(已安裝>模闆>Visual C#>Web)。選擇ASP.NET Web Application(ASP.NET Web應用程式)模闆,将project名稱命名為“ProductService”。

Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2建立OData v4端點)...

在New Project(建立項目)對話框裡選擇Empty(空模闆)。在"Add folders and core references..."(為下面對象加入目錄和核心引用)。擇Web API,然後點選OK(确定)。

Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2建立OData v4端點)...

安裝OData包

在Tools(工具)菜單裡。選擇NuGet Package Manager > Package Manager Console(NuGet程式包管理>程式包管理器控制台)。在程式包管理器控制台視窗裡輸入:

Install-Package Microsoft.AspNet.Odata
           

該指令将會安裝最新的OData NuGet包。

加入一個Model 類(模型類)

在你的應用程式裡。一個Model(模型)就是一個展現資料實體的對象。

在Solution Explorer(解決方式資料總管)裡,右擊名為Models的目錄,在右鍵菜單裡,選擇Add > Class(加入>類)。

Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2建立OData v4端點)...
依照慣例。model classes(模型類)會被放入名為Models的目錄裡,隻是在你project裡你并不一定要遵循這種規則。

将該類命名為Product,在Product.cs檔案中,使用下面代碼替換樣本代碼。

namespace ProductService.Models
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }
}
           

Id

 屬性是這個實體的鍵。client能夠依據鍵來查詢實體。要查詢并得到

Id

 是5的 Product,它的資源路徑便是 /Products(5),在背景資料庫裡

Id

 也是主鍵。

啟用實體架構

在本次教程裡,我們将使用Entity Framework (EF) Code First來建立背景資料庫。

Web API OData并不一定須要EF,你能夠使用不論什麼可将資料實體轉換為models(模型)的資料訪問層。

首先,安裝EF的NuGet包。在Tools(工具)菜單裡。選擇NuGet Package Manager > Package Manager Console(NuGet程式包管理>程式包管理器控制台)。

在程式包管理器控制台視窗裡輸入:

Install-Package EntityFramework
           

打開Web.config檔案,将下面位于configuration 節點内。configSections節點後的部分加入至該檔案裡對應位置。

<configuration>
  <configSections>
    <!-- ... -->
  </configSections>

  <span style="background-color: rgb(255, 255, 0);"><!-- Add this: --></span>
  <connectionStrings>
    <add name="ProductsContext" connectionString="Data Source=(localdb)\v11.0; 
        Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True; 
        AttachDbFilename=|DataDirectory|ProductsContext.mdf"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
           

該設定裡加入了一個連結LocalDB(本地資料庫)的連結字元串。

當你在本地執行此程式時,本地資料庫将被使用。

下一步。在Models目錄裡加入一個名為

ProductsContext

 的類。

using System.Data.Entity;
namespace ProductService.Models
{
    public class ProductsContext : DbContext
    {
        public ProductsContext() 
                : base("name=ProductsContext")
        {
        }
        public DbSet<Product> Products { get; set; }
    }
}
           

在構造函數裡, "name=ProductsContext"給出了連接配接字元串的名稱。

配置OData Endpoint

打開檔案App_Start/WebApiConfig.cs,加入下面引用語句。

using ProductService.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
           

然後加入下面代碼至 Register方法中:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // New code:
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Product>("Products");
        config.MapODataServiceRoute(
            routeName: "ODataRoute",
            routePrefix: null,
            model: builder.GetEdmModel());
    }
}
           

這段代碼做了兩件事情

  • 建立Entity Data Model(EDM實體資料模型)
  • 添加一個Route(路由)

EDM是資料的抽象模型,EDM被用來建立服務的中繼資料檔案。

ODataConventionModelBuilder使用預設的命名規則建立EDM。這樣的方法須要少量的代碼。假設你想很多其它支配EDM的話,你能夠使用通過明白地加入屬性、鍵和導航屬性來建立EDM。

Route告訴了Web API應該如何路由Http請求至Endpoint(端點)中。你能夠通過調用MapODataServiceRoute 擴充的方法來建立OData v4 route(路由)。

假設你的程式裡有多個OData Endpoint,你須要為它們分别建立一個route,且給它們不同的Route路由名稱和字首。

加入OData控制器

控制器是處理Http請求的類。你能夠為每個OData服務的實體建立不同的控制器。

在本教程裡,你将為

Product

 實體建立一個控制器。

在Solution Explorer(解決方式資料總管)裡,右擊名為Controllers 的目錄,在右鍵菜單裡,選擇Add > Class(加入>類)。将其命名為ProductsController。

在OData v3教程裡我們使用了Add Controller對話框,但眼下還沒有OData v4版的。

在ProductsController.cs中用下面代碼替換樣本代碼。

using ProductService.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.OData;
namespace ProductService.Controllers
{
    public class ProductsController : ODataController
    {
        ProductsContext db = new ProductsContext();
        private bool ProductExists(int key)
        {
            return db.Products.Any(p => p.Id == key);
        } 
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
           

控制器使用ProductsContext類通過EF來訪問資料庫。注意,該控制器重寫了Dispose 方法來釋放ProductsContext。

這是控制的開始。下一步,我們将為全部的CRUD操作加入方法。

Querying the Entity Set 查詢實體集

加入下面代碼至ProductsController。

[EnableQuery]
public IQueryable<Product> Get()
{
    return db.Products;
}
[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
    IQueryable<Product> result = db.Products.Where(p => p.Id == key);
    return SingleResult.Create(result);
}
           

當中一個沒有參數的

Get

 方法傳回

Product

 的實體集合。而有一個參數的

Get

 方法則是通過 Product的鍵來查找對應的 Product(在這樣的情況下。鍵就是 Id屬性)。

[EnableQuery]标簽通過使用查詢設定$filter, $sort, $page 來改動查詢。具體資訊請點選Supporting OData Query Options。

Adding an Entity to the Entity Set 加入實體至實體集

為了使client能夠加入新

Product

 至資料庫中,我們加入例如以下方法至ProductsController。

public async Task<IHttpActionResult> Post(Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Products.Add(product);
    await db.SaveChangesAsync();
    return Created(product);
}
           

Updating an Entity 更新實體

OData支援兩種不同的文法來更新實體。PATCH 和PUT。

  • PATCH運作部分更新。client僅僅需指定須要更新的屬性。
  • PUT 替換整個實體。

PUT 的不利之處是client必須發送實體全部屬性的值,包含那些沒有改變的值。OData 規範書推薦使用PATCH。

無論如何。下面是PATCH和PUT 方法的代碼:

public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    var entity = await db.Products.FindAsync(key);
    if (entity == null)
    {
        return NotFound();
    }
    product.Patch(entity);
    try
    {
        await db.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ProductExists(key))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }
    return Updated(entity);
}
public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    if (key != update.Id)
    {
        return BadRequest();
    }
    db.Entry(update).State = EntityState.Modified;
    try
    {
        await db.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ProductExists(key))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }
    return Updated(update);
}
           

在 PATCH情況下,控制器使用 Delta<T>來跟蹤實體的改變。

Deleting an Entity 删除實體

為了能讓client從資料庫中删除實體,我們能夠在ProductsController中加入下面方法。

public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
    var product = await db.Products.FindAsync(key);
    if (product == null)
    {
        return NotFound();
    }
    db.Products.Remove(product);
    await db.SaveChangesAsync();
    return StatusCode(HttpStatusCode.NoContent);
}
           

原文位址:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint