標籤:efi toc result 手動 com post 控制器 斜杠 contex
程式資料庫格式標準化的開來源資料協議為了增強各種網頁應用程式之間的資料相容性,微軟公司啟動了一項旨在推廣網頁程式資料庫格式標準化的開來源資料協議(OData)計劃,於此同時,他們還發 布了一款適用於OData協議的開發工具,以方便網頁程式開發人員們使用。Open Data Protocol (開放資料協議,OData)是用來查詢和更新資料的一種Web協議,其提供了把存在於應用程式中的資料暴露出來的方式。OData運用且構建於很多 Web技術之上,比如HTTP、Atom Publishing Protocol(AtomPub)和JSON,提供了從各種應用程式、服務和存放庫中訪問資訊的能力。OData被用來從各種資料來源中暴露和訪問資訊, 這些資料來源包括但不限於:關聯式資料庫、檔案系統、內容管理系統和傳統Web網站。建立項目
在VS中建立一個新的Asp.Net Web應用項目,命名為“PersonsService”,如:
安裝Nuet包
搜尋Microsoft.AspNet.Odata包跟EntityFramework包安裝
添加Model類
Model類是一個表示應用中的資料實體的對象。
在方案總管中的Models檔案夾下,建立一個Person類:
namespace PersonsService.Models{ public class Person { public int Id { get; set; } public string Name { get; set; } public bool Gender { get; set; } public string UserName { get; set; } }} 產生資料庫
開啟Web.config檔案,在configuration元素中添加下面的connectionStrings節點:
<connectionStrings> <add name="PersonsContext" connectionString="Server=.;Database=PersonsDB;Integrated Security=True" providerName="System.Data.SqlClient"/> </connectionStrings>
在Models檔案夾下添加一個PersonsContext類:
using System.Data.Entity;namespace PersonsService.Models{ public class PersonsContext : DbContext { public PersonsContext() : base("name=PersonsContext") { } public DbSet<Person> Persons { get; set; } }}
開啟NuGet包管理器,封裝管理員控制台輸入以下命令 "enable-migrations" ,"add-migration","update-database "
這個時候開啟SQL Server 就可以看到已經建立好的資料庫
配置OData終結點
開啟App_Start/WebApiConfig.cs檔案,配置下面的新代碼
using Microsoft.OData.Edm;using PersonsService.Models;using System.Web.Http;using System.Web.OData.Builder;using System.Web.OData.Extensions;namespace PersonsService{ public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API 配置和服務 // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //構建路由服務 config.MapODataServiceRoute( routeName: "odata", routePrefix: "odata", model: GetModel() ); } private static IEdmModel GetModel() { var builder = new ODataConventionModelBuilder(); var esPerson = builder.EntitySet<Person>("Persons"); return builder.GetEdmModel(); } }}
上面的代碼做了兩件事:
- 建立了一個實體資料模型(Entity Data Model【簡稱EDM】)。
- 添加了一個路由。
EDM是一個抽象的資料模型。EDM用於建立服務中繼資料文檔。ODataConventionModelBuilder類使用預設的命名規範建立了一個EDM。這種方式需要寫的代碼最少。如果你想更多地控制EDM,那麼你可以使用 ODataModelBuilder類來建立EDM類,這樣做就要顯式添加屬性,鍵和導覽屬性。
路由(route)會告訴Web API如何將HTTP請求路由到終結點。調用MapODataServiceRoute 擴充方法可以建立一個OData v4路由。
如果你的應用有了多個OData終結點,那麼要為每個終結點建立一個單獨的路由,給每個路由一個唯一的路由名和首碼(prefix)。
添加OData控制器
控制器是處理HTTP請求的一個類。在OData應用中,應該為每個實體集建立一個單獨的控制器。而在這篇部落格中,我們只要為Person實體建立一個控制器就行了。
在Controllers檔案夾下添加一個控制器,如下:
修改控制器代碼,如下:
using PersonsService.Models;using System.Linq;using System.Web.OData;namespace PersonsService.Controllers{ public class PersonsController : ODataController { private readonly PersonsContext db = new PersonsContext(); [EnableQuery] public IQueryable<Person> Get() { return db.Persons; } [EnableQuery] public IQueryable<Person> Get([FromODataUri] int key) { return db.Persons.Where(r=> r.Id==key); } }}
這時我們手動給資料庫添加些資料,
好了,現在我們運行項目嘗試請求下
請求http://localhost:3370/odata/Persons
現在資料都出來了,試下請求單個Person
http://localhost:3370/odata/Persons(1)
一切正常
無參數的Get()方法會返回整個Person表的集合。
Get([FromODataUri] int key)方法會返回指定Id的Person。
[EnableQuery]特性允許用戶端使用查詢選項(如$filter,$sort和$page)修改查詢。
添加一個Post方法來添加Person
[HttpPost] public IHttpActionResult Post(Person person) { if (!ModelState.IsValid) { return BadRequest(ModelState); } db.Persons.Add(person); db.SaveChanges(); return Created(person); }
使用post請求http://localhost:3370/odata/Persons
看下資料庫趙六已經添加進去了,現在添加一個修改方法
OData支援兩種不同語義更新實體,包括PATCH和PUT。
- PATCH執行一個部分更新,用戶端只識別要更新的屬性。
- PUT會替換整個實體。
PUT的劣勢在於用戶端必鬚髮送實體的所有屬性,包括沒有改變的值。
OData說明書陳述了PATCH是首選。
[AcceptVerbs("PATCH", "MERGE")] public IHttpActionResult Patch([FromODataUri] int key, Delta<Person> patch) { if (!ModelState.IsValid) { return BadRequest(ModelState); } Person person = db.Persons.Find(key); if (person == null) { return NotFound(); } patch.Patch(person); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException) { throw; } return Updated(person); }
在PATCH中,控制器使用了Delta類型來跟蹤改變。
刪除實體
允許用戶端從資料庫刪除一個Person:
// DELETE: odata/Persons(5) public IHttpActionResult Delete([FromODataUri] int key) { Person person = db.Persons.Find(key); if (person == null) { return NotFound(); } db.Persons.Remove(person); db.SaveChanges(); return StatusCode(HttpStatusCode.NoContent); }
後續會補充下odata配置自訂路由的問題.
Odata 自訂路由
[EnableQuery, HttpGet] [ODataRoute("Products({id})/Default.GetCatAndTown")] public IHttpActionResult GetCatAndTown([FromODataUri] int id) { var list = db.Products.Where(r => r.Id == id); return Ok(list); }
當然這個時候我們請求http://localhost:6785//Odata/Products(1)/Default.GetCatAndTown會報錯404,解決方案是添加一個尾部的斜杠到請求的網址
這個時候我們http://localhost:6785//Odata/Products(1)/Default.GetCatAndTown/就會好了,具體原因不詳。或者是修改web.config檔案
<system.webServer> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0Custom" path="/odata*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer>
ASP.NET Web API 2 OData v4教程