概述

开放式数据协议(OData) 是用于在 web 数据访问协议。它提供统一的方式来构造数据、 查询的数据和操纵数据集通过 CRUD 操作。它支持 AtomPub (XML) 和 JSON 格式。它还定义的方式来公开元数据有关的数据。客户端可以使用元数据来发现的类型信息和数据集的关系。

ASP.NET Web API 容易地创建一个数据集的 OData 终结点。您可以控制到底哪些 OData 操作终结点支持。你可以承载多个 OData 端点,除了非 OData 端点。你有你的数据模型后, 端业务逻辑和数据层的完全控制。

项目搭建

添加模型

在Models文件夹下,添加Product.cs:

namespace ApiDemo02.Models
{
/// <summary>产品实体类</summary>
public class Product
{
/// <summary>产品ID</summary>
public int ID { get; set; } /// <summary>产品名称</summary>
public string Name { get; set; } /// <summary>产品类别</summary>
public string Genre { get; set; } /// <summary>产品价格</summary>
public decimal Price { get; set; }
}
}

  注:先生成一下项目!

添加模型

在 Controllers文件夹下,添加控制器:

点击“添加”,则出现下面错误:

原因:前面我提示过,创建新实体后,先生成一下项目。这里我还是忘记了,生成项目后,再照上面步骤添加控制器,ok!

支架自动创建了两个文件:

修改配置

打开App_Start文件下的WebApiConfig.cs,修改代码:

using ApiDemo02.Models;
using System.Web.Http;
using System.Web.Http.OData.Builder; namespace ApiDemo02
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services //创建 OData 端点的实体数据模型 (EDM)
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
//添加设置为 EDM 实体
builder.EntitySet<Product>("Products");
//添加终结点的路由
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel()); // Web API routes
//config.MapHttpAttributeRoutes(); //config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
}
}
}

  EDM 是一种抽象的数据模型。EDM 用于创建元数据文件和定义服务的 Uri。ODataConventionModelBuilder通过使用一组默认的命名约定 EDM 创建 EDM,这种方法要求最少代码。如果你想对 EDM 的更多控制,你可以使用ODataModelBuilder类来显式地创建 EDM 中的通过添加属性、 键和导航属性。

EntitySet<Product>("Product")中"Product"的字符串定义是控制器的名称。终结点可以有多个实体集。EntitySet < T >对应一个实体集,然后再定义一个对应的控制器。

MapODataRoute方法第一个参数是路线的友好名称。您服务的客户端看不到此名称。第二个参数是为终结点的 URI 前缀。鉴于此代码,为产品实体集的 URI 是 http:// /odata/Product。您的应用程序可以有多个 OData 端点。对于每个终结点,调用MapODataRoute ,并提供一个独特的路由名称和唯一的 URI 前缀。

在修改一下根目录下的Web.config中的<connectionStrings>数据库连接字符串节点:

  <connectionStrings>
<add name="ProductContext"
connectionString="Data Source=(localdb)\v11.0; Initial Catalog=ProductDB; Integrated Security=True;
MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|ProductDB.mdf"
providerName="System.Data.SqlClient" />
</connectionStrings>

注:这一小节EDM有点难理解,我也得好好琢磨一下!

迁移及初始化数据库

打开VS“工具”:

查看迁移帮助:

启用迁移:

这时,会多出Migrations文件夹及其下Configuration.cs文件:

修改Migrations文件夹下Configuration.cs文件来添加种子数据:

using ApiDemo02.Models;
using System.Data.Entity.Migrations; namespace ApiDemo02.Migrations
{
internal sealed class Configuration : DbMigrationsConfiguration<ApiDemo02.Models.ProductContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
} protected override void Seed(ApiDemo02.Models.ProductContext context)
{
context.Products.AddOrUpdate(new Product[]
{
new Product() { ID = 1, Name = "Hat", Price = 15, Genre = "Apparel" },
new Product() { ID = 2, Name = "Socks", Price = 5, Genre = "Apparel" },
new Product() { ID = 3, Name = "Scarf", Price = 12, Genre = "Apparel" },
new Product() { ID = 4, Name = "Yo-yo", Price = 4.95M, Genre = "Toys" },
new Product() { ID = 5, Name = "Puzzle", Price = 8, Genre = "Toys" },
});
}
}
}

  添加迁移:

更新数据库:

检查数据库文件:

至此,数据库创建OK,也有了模拟数据!

访问测试

这里使用HTTP工具来模拟请求,所以先去下载(http://www.telerik.com/fiddler)安装Fiddler4。

运行项目,看一下端口:

注:这里Chrome浏览器以xml方式读取,如果使用IE浏览器,它默认是json方式,会提示下载!

打开fiddler,点Composer:

点Execute后,并查看xml结果:

响应json请求:

查看结果:

获取元数据,不论是否json请求,它返回xml格式:

查看结果:

读取Product数据:

查看数据:

由于截图太多了,我就不演示POST等其它请求了!

小结

回顾一下Cntrollers下ProductController.cs的代码:

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Http.OData;
using ApiDemo02.Models; namespace ApiDemo02.Controllers
{
/*
若要为此控制器添加路由,请将这些语句合并到 WebApiConfig 类的 Register 方法中。请注意 OData URL 区分大小写。 using System.Web.Http.OData.Builder;
using ApiDemo02.Models;
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product>("Product");
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
*/
public class ProductController : ODataController
{
private ProductContext db = new ProductContext(); // GET odata/Product
[Queryable]
public IQueryable<Product> GetProduct()
{
return db.Products;
} // GET odata/Product(5)
[Queryable]
public SingleResult<Product> GetProduct([FromODataUri] int key)
{
return SingleResult.Create(db.Products.Where(product => product.ID == key));
} // PUT odata/Product(5)
public IHttpActionResult Put([FromODataUri] int key, Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} if (key != product.ID)
{
return BadRequest();
} db.Entry(product).State = EntityState.Modified; try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
} return Updated(product);
} // POST odata/Product
public IHttpActionResult Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} db.Products.Add(product);
db.SaveChanges(); return Created(product);
} // PATCH odata/Product(5)
[AcceptVerbs("PATCH", "MERGE")]
public IHttpActionResult Patch([FromODataUri] int key, Delta<Product> patch)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} Product product = db.Products.Find(key);
if (product == null)
{
return NotFound();
} patch.Patch(product); try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
} return Updated(product);
} // DELETE odata/Product(5)
public IHttpActionResult Delete([FromODataUri] int key)
{
Product product = db.Products.Find(key);
if (product == null)
{
return NotFound();
} db.Products.Remove(product);
db.SaveChanges(); return StatusCode(HttpStatusCode.NoContent);
} protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
} private bool ProductExists(int key)
{
return db.Products.Count(e => e.ID == key) > 0;
}
}
}

  真的很神奇地采用数据库上下文帮我们封装好数据库操作!疑问:还有必要再封装成仓储库方式吗? 再有WebApi如何路由的和JSON序列化/格式化,有空再介绍。

(注:截图过多,看起来花花绿绿地,抱歉了!)

ASP.NET WebApi 开放数据的更多相关文章

  1. ASP.NET WebApi技术从入门到实战演练

    一.课程介绍 曾经有一位不知名的讲师说过这么一句名言: 一门RPC技术不会,那么千万万门RPC技术将都不会!在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, An ...

  2. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  3. 使用Asp.net WebAPI 快速构建后台数据接口

    现在的互联网应用,无论是web应用,还是移动APP,基本都需要实现非常多的数据访问接口.其实对一些轻应用来说Asp.net WebAPI是一个很快捷简单并且易于维护的后台数据接口框架.下面我们来快速构 ...

  4. ASP.NET WebApi OWIN 实现 OAuth 2.0

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...

  5. OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client

    一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open protocol to allow the creation and consumption of quer ...

  6. [转]OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service & Client

    本文转自:http://www.cnblogs.com/bluedoctor/p/4384659.html 一.概念介绍 1.1,什么是OData? 还是看OData官网的简单说明: An open ...

  7. Asp.Net WebApi一个简单的Token验证

    1.前言: WebAPI主要开放数据给手机APP,Pad,其他需要得知数据的系统,或者软件应用.Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能.我上次写的<Asp.Net MV ...

  8. [转]ASP.NET WebApi OWIN 实现 OAuth 2.0

    OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth 允许用户提供一个令牌, ...

  9. Asp.Net WebApi核心对象解析(上篇)

    生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...

随机推荐

  1. 用户 'IIS APPPOOL\IdealTest' 登录失败解决方案

    原文:用户 'IIS APPPOOL\IdealTest' 登录失败解决方案 运行MVC框架后可能会提示“用户 'IIS APPPOOL\IdealTest' 登录失败” 详细堆栈信息如下 说明: 执 ...

  2. Java一些八卦集合类

    Map 和 Set关系 Map和Set事实基础的朋友,有着千丝万缕的联系. Map它可以被看作是Set延期.从何时起Set内容存储在key-value的值当表单.这个Set实际上可以作为Map使用.反 ...

  3. crm使用soap删除实体

    //C# 代码: //DeleteEntityRequest request = new DeleteEntityRequest(); //request.LogicalName = "ne ...

  4. 纠错《COM技术内幕》之ProgID

    近期在看<COM技术内幕>,看到第六章时发现该章节在解释ProgID时有点错误,特此记录一下,也给正在学习COM的小伙伴们一个提示. 并且我发现该问题存在于一些非常多大型软件的COM组件中 ...

  5. iOS10收集IDFA,植入第三方广告[终结]--ADMob

    [PS: 前段时间,公司做ASO推广,需要在应用中收集IDFA值,跟广告平台做交互!于是有了这个需求--] 1.首先,考虑了一下情况(自己懒 -_-#),就直接在首页上写了一个Banner,循环加载广 ...

  6. SVN & Git (一)

    (一)SVN的使用.CornerStone图形化管理工具! SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS. ...

  7. android ListView之BaseAdapter的使用方式

    通常在使用自己定义适配器的时候,我们都会掌握一种固定的模式.充分利用convertView+缓存的方式. private ArrayList<ListBean> list ; privat ...

  8. 常见浏览器扩展开发笔记(chrome firefox 360 baidu qq sougou liebao uc opera)

    浏览器扩展开发貌似时下很冷门啊,但是不少企业还是有类似的应用,360的抢票插件啊,笔者最近在做的网页翻译扩展之类的.笔者在开发的过程中,遇到了不少坑,说是坑,说白了就是各个厂商支持的API不统一导致的 ...

  9. POJ 3390 Print Words in Lines(DP)

    Print Words in Lines Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1624 Accepted: 864 D ...

  10. 单元测试之Qunit

    单元测试之Qunit 前言 因为公司开发了一套javascript SDK需要测试,在网上找了很久,找到了JQuery团队开发的QUnit,和基于JUnit的JsUnit,还有一些还没有看,先讲讲QU ...