您的位置:首页 > 其它

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、创建一个实体对象
设置数据库连接

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

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息