开放数据协议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程序包管理>程序包管理器控制台)。在程序包管理器控制台视窗里输入:

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);
}

原文地址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. word文档的导出(用freemarker模板导出)(桃)

    1.将要导出的word文档另存为xml格式的 2.用文档编辑器打开(如:notepad++),将要展示的数据用${name}的形式替换,“name”对应数据库中的字段 3.根据模板生成 package ...

  2. 开始学习es6(一) 搭建个es6的开发环境

    1.开始学习es6 如果想在浏览器跑es6  需要给es6个环境 因为一直用vue-cli全家桶 这样虽然方便 但如果用es6需要跑起个vue全家桶 于是想到可以用gulp搭建个开发环境 首先需要1. ...

  3. python作为计算器(数学用法)

    1.基本的加减乘除与取余运算 >>> print(5+10) 15 >>> print(5-10) -5 >>> print(5*10) 50 & ...

  4. 【Visual Studio】error C2220: 警告被视为错误 - 没有生成“object”文件 (转)

    原文转自 http://www.cnblogs.com/kex1n/archive/2011/10/19/2217266.html [错误原因] 该文件的代码页为英文,而我们系统中的代码页为中文. [ ...

  5. XMPP协议实现原理介绍(转)

    XMPP协议简介   XMPP(Extensible Messageing and Presence Protocol:可扩展消息与存在协议)是目前主流的四种IM(IM:instant messagi ...

  6. Java线程的中断

    引言 Java没有提供任何机制来安全地终止线程,但提供了中断机制,即thread.interrupt()方法.线程中断是一种协作式的机制,并不是说调用了中断方法之后目标线程一定会立即中断,而是发送了一 ...

  7. Codeforces Gym 100203G Good elements 暴力乱搞

    原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 考虑暴力的复杂度是O(n^3),所以 ...

  8. Parameter Binding in ASP.NET Web API #Reprinted

    http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

  9. 【Protocol Buffers】grpc默认使用的Google 开源的一套成熟的结构数据序列化机制

    grpc默认使用的Google 开源的一套成熟的结构数据序列化机制 参考地址:https://blog.csdn.net/shensky711/article/details/69696392 参考地 ...

  10. android特效集合

    https://github.com/Trinea/android-open-project http://www.cnblogs.com/hawkon/p/3593709.html http://i ...