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”。
在New Project(新建项目)对话框里选择Empty(空模板)。在"Add
folders and core references..."(为下面对象加入目录和核心引用)。择Web API,然后点击OK(确定)。
选
安装OData包
在Tools(工具)菜单里。选择NuGet
Package Manager > Package
Manager Console(NuGet程序包管理>程序包管理器控制台)。在程序包管理器控制台视窗里输入:
- Install-Package Microsoft.AspNet.Odata
该命令将会安装最新的OData NuGet包。
加入一个Model 类(模型类)
在你的应用程序里。一个Model(模型)就是一个展现数据实体的对象。
在Solution Explorer(解决方式资源管理器)里,右击名为Models的目录,在右键菜单里,选择Add > Class(加入>类)。
依照惯例。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);
- }
Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2创建OData v4端点)的更多相关文章
- [转]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- ...
- [水煮 ASP.NET Web API2 方法论](12-1)创建 OData
问题 怎样用在 Web API 中创建 OData 服务. 解决方案 对于我们来说,在 Web API 中使用 OData最简单的方式就是使用 ASP.NET 模板来创建Odata Controlle ...
- Asp.Net Web API 2第十八课——Working with Entity Relations in OData
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文的示例代码的下载地址 ...
- 【ASP.NET MVC系列】浅谈ASP.NET MVC 路由
ASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操作 ...
- 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 ...
- 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 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十二) 代码重构使用反射工厂解耦(一)缓存切换
前言 上一篇中,我们用了反射工厂来解除BLL和UI层耦合的问题.当然那是最简单的解决方法,再复杂一点的程序可能思路相同,但是在编程细节中需要考虑的就更多了,比如今天我在重构过程中遇到的问题.也是接下来 ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(一) 之 基层数据搭建,让数据活起来(数据获取)
大家好,本篇是接上一篇 ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(零) 前言 ASP.NET SignalR WebIM系列第二篇.本篇会带领大家将 LayIM ...
- ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(十一) 代码重构使用反射工厂解耦
前言 自从此博客发表以及代码开源以来,得到了许多人的关注.也没许多吧,反正在我意料之外的.包括几位大牛帮我做订阅号推广,真的很感谢他们.另外,还有几个高手给我提了一些架构上的问题.其实本身这个项目是没 ...
随机推荐
- bzoj 3456 城市规划 无向简单连通图个数 多项式求逆
题目大意 求n个点的无向简单连通图个数 做法1 \(f[i]\)表示i个点的无向简单连通图个数 \(g[i]=2^{\frac {i*(i-1)}{2}}\)表示i个点的无向简单图个数(不要求连通) ...
- grunt 入门 应用grunt对代码进行压缩
1.什么是grunt grunt的官方解释是:javascript世界的构建工具. 为何要构建工具? 一句话:自动化.对于需要反复重复的任务,例如压缩(minification).编译.单元测试.li ...
- php--转码函数
最近在用dedecms二次开发会员功能:大家都知道dedecms编码是GBK格式的:所以在我们在项目中经常需要转码,在我了解中有两种转码方式:一是:iconv:二是mb_convert_encodin ...
- 数据结构自己实现——Linklist
//单???链???表??? #include <iostream> using namespace std; typedef char datatype; typedef struct ...
- 洛谷——P1126 机器人搬重物
P1126 机器人搬重物 题目描述 机器人移动学会(RMI)现在正尝试用机器人搬运物品.机器人的形状是一个直径1.6米的球.在试验阶段,机器人被用于在一个储藏室中搬运货物.储藏室是一个N*M的网格,有 ...
- 湖南集训day2
难度:☆☆ /*显然可以前缀和*/ #include<iostream> #include<cstdio> #include<cstring> #define N ...
- 构建伪Update服务器工具isr-evilgrade
构建伪Update服务器工具isr-evilgrade 现在大部分软件都提供更新功能.软件一旦运行,就自动检查对应的Update服务器.如果发现新版本,就会提示用户,并进行下载和安装.而用户往往相 ...
- k8s入门简介
1.docker的三种编排工具 Docker的第一类编排工具: a.docker compose(docker原生):只能对一个主机上的容器进行编排,无法编排多个主机上的容器; b.docker sw ...
- 第3章 CentOS常用命令
一.CentOS常用命令 1.1 文件和目录 # cd /home 进入 '/home' 目录 # cd .. ...
- java -agent与Javassist
javassist api https://blog.csdn.net/u011425751/article/details/51917895 晚些时候再补充一些使用注意事项.