开放数据协议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操作。

教程里使用的软件版本号

教程版本号

点击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”。

在New Project(新建项目)对话框里选择Empty(空模板)。在"Add
folders and core references..."(为下面对象加入目录和核心引用)。择Web API,然后点击OK(确定)。

安装OData包

在Tools(工具)菜单里。选择NuGet
Package Manager > Package
Manager Console(NuGet程序包管理>程序包管理器控制台)。在程序包管理器控制台视窗里输入:

  1. Install-Package Microsoft.AspNet.Odata

该命令将会安装最新的OData NuGet包。

加入一个Model 类(模型类)

在你的应用程序里。一个Model(模型)就是一个展现数据实体的对象。

在Solution Explorer(解决方式资源管理器)里,右击名为Models的目录,在右键菜单里,选择Add > Class(加入>类)。

依照惯例。model classes(模型类)会被放入名为Models的目录里,只是在你project里你并不一定要遵循这种规则。

将该类命名为Product,在Product.cs文件中,使用下面代码替换样本代码。

  1. namespace ProductService.Models
  2. {
  3. public class Product
  4. {
  5. public int Id { get; set; }
  6. public string Name { get; set; }
  7. public decimal Price { get; set; }
  8. public string Category { get; set; }
  9. }
  10. }

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程序包管理>程序包管理器控制台)。

在程序包管理器控制台视窗里输入:

  1. Install-Package EntityFramework

打开Web.config文件,将下面位于configuration 节点内。configSections节点后的部分加入至该文件里对应位置。

  1. <configuration>
  2. <configSections>
  3. <!-- ... -->
  4. </configSections>
  5.  
  6. <span style="background-color: rgb(255, 255, 0);"><!-- Add this: --></span>
  7. <connectionStrings>
  8. <add name="ProductsContext" connectionString="Data Source=(localdb)\v11.0;
  9. Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True;
  10. AttachDbFilename=|DataDirectory|ProductsContext.mdf"
  11. providerName="System.Data.SqlClient" />
  12. </connectionStrings>

该设置里加入了一个链接LocalDB(本地数据库)的链接字符串。

当你在本地执行此程序时,本地数据库将被使用。

下一步。在Models目录里加入一个名为ProductsContext 的类。

  1. using System.Data.Entity;
  2. namespace ProductService.Models
  3. {
  4. public class ProductsContext : DbContext
  5. {
  6. public ProductsContext()
  7. : base("name=ProductsContext")
  8. {
  9. }
  10. public DbSet<Product> Products { get; set; }
  11. }
  12. }

在构造函数里,"name=ProductsContext"给出了连接字符串的名称。

配置OData Endpoint

打开文件App_Start/WebApiConfig.cs,加入下面引用语句。

  1. using ProductService.Models;
  2. using System.Web.OData.Builder;
  3. using System.Web.OData.Extensions;

然后加入下面代码至Register方法中:

  1. public static class WebApiConfig
  2. {
  3. public static void Register(HttpConfiguration config)
  4. {
  5. // New code:
  6. ODataModelBuilder builder = new ODataConventionModelBuilder();
  7. builder.EntitySet<Product>("Products");
  8. config.MapODataServiceRoute(
  9. routeName: "ODataRoute",
  10. routePrefix: null,
  11. model: builder.GetEdmModel());
  12. }
  13. }

这段代码做了两件事情

  • 创建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中用下面代码替换样本代码。

  1. using ProductService.Models;
  2. using System.Data.Entity;
  3. using System.Data.Entity.Infrastructure;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Threading.Tasks;
  7. using System.Web.Http;
  8. using System.Web.OData;
  9. namespace ProductService.Controllers
  10. {
  11. public class ProductsController : ODataController
  12. {
  13. ProductsContext db = new ProductsContext();
  14. private bool ProductExists(int key)
  15. {
  16. return db.Products.Any(p => p.Id == key);
  17. }
  18. protected override void Dispose(bool disposing)
  19. {
  20. db.Dispose();
  21. base.Dispose(disposing);
  22. }
  23. }
  24. }

控制器使用ProductsContext类通过EF来訪问数据库。注意,该控制器重写了Dispose 方法来释放ProductsContext。

这是控制的開始。下一步,我们将为全部的CRUD操作加入方法。

Querying the Entity Set 查询实体集

加入下面代码至ProductsController。

  1. [EnableQuery]
  2. public IQueryable<Product> Get()
  3. {
  4. return db.Products;
  5. }
  6. [EnableQuery]
  7. public SingleResult<Product> Get([FromODataUri] int key)
  8. {
  9. IQueryable<Product> result = db.Products.Where(p => p.Id == key);
  10. return SingleResult.Create(result);
  11. }

当中一个没有參数的Get 方法返回Product 的实体集合。而有一个參数的Get 方法则是通过Product的键来查找对应的Product(在这样的情况下。键就是Id属性)。

[EnableQuery]标签通过使用查询设置$filter,
$sort, $page 来改动查询。具体信息请点击Supporting
OData Query Options

Adding an Entity to the Entity Set 加入实体至实体集

为了使client能够加入新Product 至数据库中,我们加入例如以下方法至ProductsController。

  1. public async Task<IHttpActionResult> Post(Product product)
  2. {
  3. if (!ModelState.IsValid)
  4. {
  5. return BadRequest(ModelState);
  6. }
  7. db.Products.Add(product);
  8. await db.SaveChangesAsync();
  9. return Created(product);
  10. }

Updating an Entity 更新实体

OData支持两种不同的语法来更新实体。PATCH 和PUT。

  • PATCH运行部分更新。client仅仅需指定须要更新的属性。

  • PUT 替换整个实体。

PUT 的不利之处是client必须发送实体全部属性的值,包含那些没有改变的值。OData
规范书
推荐使用PATCH。

无论如何。下面是PATCH和PUT 方法的代码:

  1. public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)
  2. {
  3. if (!ModelState.IsValid)
  4. {
  5. return BadRequest(ModelState);
  6. }
  7. var entity = await db.Products.FindAsync(key);
  8. if (entity == null)
  9. {
  10. return NotFound();
  11. }
  12. product.Patch(entity);
  13. try
  14. {
  15. await db.SaveChangesAsync();
  16. }
  17. catch (DbUpdateConcurrencyException)
  18. {
  19. if (!ProductExists(key))
  20. {
  21. return NotFound();
  22. }
  23. else
  24. {
  25. throw;
  26. }
  27. }
  28. return Updated(entity);
  29. }
  30. public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update)
  31. {
  32. if (!ModelState.IsValid)
  33. {
  34. return BadRequest(ModelState);
  35. }
  36. if (key != update.Id)
  37. {
  38. return BadRequest();
  39. }
  40. db.Entry(update).State = EntityState.Modified;
  41. try
  42. {
  43. await db.SaveChangesAsync();
  44. }
  45. catch (DbUpdateConcurrencyException)
  46. {
  47. if (!ProductExists(key))
  48. {
  49. return NotFound();
  50. }
  51. else
  52. {
  53. throw;
  54. }
  55. }
  56. return Updated(update);
  57. }

在PATCH情况下,控制器使用Delta<T>来跟踪实体的改变。

Deleting an Entity 删除实体

为了能让client从数据库中删除实体,我们能够在ProductsController中加入下面方法。

  1. public async Task<IHttpActionResult> Delete([FromODataUri] int key)
  2. {
  3. var product = await db.Products.FindAsync(key);
  4. if (product == null)
  5. {
  6. return NotFound();
  7. }
  8. db.Products.Remove(product);
  9. await db.SaveChangesAsync();
  10. return StatusCode(HttpStatusCode.NoContent);
  11. }

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

Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2创建OData v4端点)的更多相关文章

  1. [转]Creating an OData v3 Endpoint with Web API 2

    本文转自:https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata- ...

  2. [水煮 ASP.NET Web API2 方法论](12-1)创建 OData

    问题 怎样用在 Web API 中创建 OData 服务. 解决方案 对于我们来说,在 Web API 中使用 OData最简单的方式就是使用 ASP.NET 模板来创建Odata Controlle ...

  3. Asp.Net Web API 2第十八课——Working with Entity Relations in OData

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文的示例代码的下载地址 ...

  4. 【ASP.NET MVC系列】浅谈ASP.NET MVC 路由

    ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...

  5. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  6. ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 Part 5 (by TAISEER)

    https://www.cnblogs.com/KimmyLee/p/6430474.html https://www.cnblogs.com/rocketRobin/p/9077523.html h ...

  7. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换

    前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...

  8. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)

    大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言  ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...

  9. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十一) 代码重构使用反射工厂解耦

    前言 自从此博客发表以及代码开源以来,得到了许多人的关注.也没许多吧,反正在我意料之外的.包括几位大牛帮我做订阅号推广,真的很感谢他们.另外,还有几个高手给我提了一些架构上的问题.其实本身这个项目是没 ...

随机推荐

  1. bzoj 3456 城市规划 无向简单连通图个数 多项式求逆

    题目大意 求n个点的无向简单连通图个数 做法1 \(f[i]\)表示i个点的无向简单连通图个数 \(g[i]=2^{\frac {i*(i-1)}{2}}\)表示i个点的无向简单图个数(不要求连通) ...

  2. grunt 入门 应用grunt对代码进行压缩

    1.什么是grunt grunt的官方解释是:javascript世界的构建工具. 为何要构建工具? 一句话:自动化.对于需要反复重复的任务,例如压缩(minification).编译.单元测试.li ...

  3. php--转码函数

    最近在用dedecms二次开发会员功能:大家都知道dedecms编码是GBK格式的:所以在我们在项目中经常需要转码,在我了解中有两种转码方式:一是:iconv:二是mb_convert_encodin ...

  4. 数据结构自己实现——Linklist

    //单???链???表??? #include <iostream> using namespace std; typedef char datatype; typedef struct ...

  5. 洛谷——P1126 机器人搬重物

    P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...

  6. 湖南集训day2

    难度:☆☆ /*显然可以前缀和*/ #include<iostream> #include<cstdio> #include<cstring> #define N ...

  7. 构建伪Update服务器工具isr-evilgrade

    构建伪Update服务器工具isr-evilgrade   现在大部分软件都提供更新功能.软件一旦运行,就自动检查对应的Update服务器.如果发现新版本,就会提示用户,并进行下载和安装.而用户往往相 ...

  8. k8s入门简介

    1.docker的三种编排工具 Docker的第一类编排工具: a.docker compose(docker原生):只能对一个主机上的容器进行编排,无法编排多个主机上的容器; b.docker sw ...

  9. 第3章 CentOS常用命令

    一.CentOS常用命令 1.1 文件和目录 # cd /home                        进入 '/home' 目录 # cd ..                       ...

  10. java -agent与Javassist

    javassist api https://blog.csdn.net/u011425751/article/details/51917895 晚些时候再补充一些使用注意事项.