VS2015 使用ODataV4创建Web Api和OData客户端
2017-10-18 17:04
465 查看
OData - Open Data Protocol,是一个设计和使用RESTful API的标准。REST本身只是一个构建web服务的思想和理念,其没有规定一个统一的标准来限制开发人员该如何设计RESTful API。其实我们实际开发中的确也没有遵循某个统一的标准去设计WebAPI。因为大多数场景下,遵循一个统一的标准并不是必要的。但在某些场景下,有这样一个标准却能带来很大的好处。
OData的理想是, 无论哪个组织构建的RESTful API,只要其符合OData标准。其他组织就可以按照OData标准中定义的方式去使用这个API获取/修改资源。这个可以类比SQL标准之于RDBMS关系。无论什么关系型数据库,如果其声称支持SQL标准,任何人就可以使用标准SQL查询语句来查询数据。
标准化的另一个好处:可以将Odata协议实现到一个通用的类库中,通过这个类库去创建和访问RESTful API可以减少开发人员的工作量。
一、新建一个空的WebApi项目
二、添加包Microsoft.AspNet.OData包
1、工具菜单--NuGet包管理器--程序包管理器控制台:
2、输入Install-Package Microsoft.AspNet.OData 命令
三、添加EntityFramework包(如何已经有数据则可以使用自己的数据源,直接跳过)
1、输入Install-Package EntityFramework 命令
2、创建一个实体对象
设置数据库连接
三、配置OData终结点
1、打开WebApiConfig配置EDM
2、添加路由并设置查询参数
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
config.MapODataServiceRoute("ProductOData", null, GenerateEdmModel());
//设置查询参数方式一
//config.Select().OrderBy().Filter().Expand().MaxTop(100).Count();
//设置查询参数方式二
DefaultQuerySettings query = new DefaultQuerySettings()
{
EnableCount = true,
EnableExpand = true,
EnableFilter = true,
EnableOrderBy = true,
EnableSelect = true,
MaxTop = 100
};
config.SetDefaultQuerySettings(query);
}
四、添加OData控制器
数据库连接
public class ProductsController : ODataController
{
private ODataAPIContext db = new ODataAPIContext();
// GET Products
//[Queryable]
[EnableQuery]
public IQueryable<Product> GetProducts()
{
return db.Products;
}
// GET Products(5)
//[Queryable]
[EnableQuery]
public SingleResult<Product> GetProduct([FromODataUri] int key)
{
return SingleResult.Create(db.Products.Where(product => product.ID == key));
}
/// <summary>
/// 更新、 修改
/// </summary>
/// <param name="key"></param>
/// <param name="product"></param>
/// <returns></returns>
// PUT Products(5)
public async Task<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;
4000
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(product);
}
/// <summary>
/// 新增
/// </summary>
/// <param name="product"></param>
/// <returns></returns>
// POST Products
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="patch"></param>
/// <returns></returns>
// PATCH Products(5)
[AcceptVerbs("PATCH", "MERGE")]
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> patch)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Product product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
patch.Patch(product);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(product);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
// DELETE Products(5)
public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
Product product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
db.Products.Remove(product);
await db.SaveChangesAsync();
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;
}
}
运行查看
2、查看$metadata
3、查看集合
五、添加OData客户端
1、工具--扩展和更新--安装“OData v4 Client Code Generator”
2、添加控制台程序
3、添加新建项
4、在ODataClient.tt文件中修改MetadataDocumentUri路径
5、保存或者在文件上面右击运行自定义工具,生成相应文件
6、执行
class Program
{
static void Main(string[] args)
{
const string serviceUri = "http://localhost:57244/";
var container = new DefaultContainer(new Uri(serviceUri));
foreach (var p in container.Products)
{
Console.WriteLine("{0} {1}", p.ID, p.Name);
}
Console.Read();
}
}
OData的理想是, 无论哪个组织构建的RESTful API,只要其符合OData标准。其他组织就可以按照OData标准中定义的方式去使用这个API获取/修改资源。这个可以类比SQL标准之于RDBMS关系。无论什么关系型数据库,如果其声称支持SQL标准,任何人就可以使用标准SQL查询语句来查询数据。
标准化的另一个好处:可以将Odata协议实现到一个通用的类库中,通过这个类库去创建和访问RESTful API可以减少开发人员的工作量。
一、新建一个空的WebApi项目
二、添加包Microsoft.AspNet.OData包
1、工具菜单--NuGet包管理器--程序包管理器控制台:
2、输入Install-Package Microsoft.AspNet.OData 命令
三、添加EntityFramework包(如何已经有数据则可以使用自己的数据源,直接跳过)
1、输入Install-Package EntityFramework 命令
2、创建一个实体对象
设置数据库连接
public class Product { [Key] public int ID { get; set; } public String Name { get; set; } // [IgnoreDataMember] 属性表示在EDM中不可见 [IgnoreDataMember] public string Category { get; set; } }
三、配置OData终结点
1、打开WebApiConfig配置EDM
private static IEdmModel GenerateEdmModel() { var builder = new ODataConventionModelBuilder { Namespace = "OdataModel", ContainerName = "DefaultContainer", }; builder.EntitySet<Product>("Products"); return builder.GetEdmModel(); }
2、添加路由并设置查询参数
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
config.MapODataServiceRoute("ProductOData", null, GenerateEdmModel());
//设置查询参数方式一
//config.Select().OrderBy().Filter().Expand().MaxTop(100).Count();
//设置查询参数方式二
DefaultQuerySettings query = new DefaultQuerySettings()
{
EnableCount = true,
EnableExpand = true,
EnableFilter = true,
EnableOrderBy = true,
EnableSelect = true,
MaxTop = 100
};
config.SetDefaultQuerySettings(query);
}
四、添加OData控制器
public class ODataAPIContext : DbContext { public ODataAPIContext() : base("ODataDB") { } public DbSet<Product> Products { get; set; } static ODataAPIContext() { //关闭数据库初始化操作 Database.SetInitializer<ODataAPIContext>(null); } }
数据库连接
public class ProductsController : ODataController
{
private ODataAPIContext db = new ODataAPIContext();
// GET Products
//[Queryable]
[EnableQuery]
public IQueryable<Product> GetProducts()
{
return db.Products;
}
// GET Products(5)
//[Queryable]
[EnableQuery]
public SingleResult<Product> GetProduct([FromODataUri] int key)
{
return SingleResult.Create(db.Products.Where(product => product.ID == key));
}
/// <summary>
/// 更新、 修改
/// </summary>
/// <param name="key"></param>
/// <param name="product"></param>
/// <returns></returns>
// PUT Products(5)
public async Task<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;
4000
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(product);
}
/// <summary>
/// 新增
/// </summary>
/// <param name="product"></param>
/// <returns></returns>
// POST Products
public async Task<IHttpActionResult> Post(Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Products.Add(product);
await db.SaveChangesAsync();
return Created(product);
}
/// <summary>
///
/// </summary>
/// <param name="key"></param>
/// <param name="patch"></param>
/// <returns></returns>
// PATCH Products(5)
[AcceptVerbs("PATCH", "MERGE")]
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> patch)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Product product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
patch.Patch(product);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(product);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
// DELETE Products(5)
public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
Product product = await db.Products.FindAsync(key);
if (product == null)
{
return NotFound();
}
db.Products.Remove(product);
await db.SaveChangesAsync();
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;
}
}
运行查看
2、查看$metadata
3、查看集合
五、添加OData客户端
1、工具--扩展和更新--安装“OData v4 Client Code Generator”
2、添加控制台程序
3、添加新建项
4、在ODataClient.tt文件中修改MetadataDocumentUri路径
5、保存或者在文件上面右击运行自定义工具,生成相应文件
6、执行
class Program
{
static void Main(string[] args)
{
const string serviceUri = "http://localhost:57244/";
var container = new DefaultContainer(new Uri(serviceUri));
foreach (var p in container.Products)
{
Console.WriteLine("{0} {1}", p.ID, p.Name);
}
Console.Read();
}
}
相关文章推荐
- Create an OData v4 Endpoint Using ASP.NET Web API 2.2(使用ASP.NET Web API 2.2创建OData v4端点)
- vs2015使用向导创建SOUI项目问题记录
- VS2015用C++创建动态库DLL及使用
- 如何使用ASP.NET Web API OData在Oracle中使用Entity Framework 6.x Code-First方式开发 OData V4 Service
- 使用VS2015创建MFC项目介绍
- [转]Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务
- 题目:使用VS2015与VS2013 创建C++动态链接库并调用
- 使用CMake创建CEF3的vs2015的工程文件
- VS2015使用小技巧 使用快捷键创建for循环(正向,逆向)
- 使用VS2015创建纯C动态库。
- WPF:使用VS2015 创建自定义项模板
- VS2015C#使用Install Shield创建快捷方式为何属性中“目标”和“目标位置”为灰色
- 【初级】VS2015/MFC动态创建工具栏1(使用图标创建工具栏)
- 使用VS2015创建和调用dll文件
- VS2015使用小技巧 如何使用VS2015创建写HTML代码的项目
- 使用VS2015 创建C++动态链接库并调用
- Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务
- 使用VS2015创建和使用动态链接库-图文详解
- OData v4 - Web API 轻量级应用(使用Entity Framwork)-Endpoint
- Web Api系列教程第2季(OData篇)(二)——使用Web Api创建只读的OData服务