在ASP.NET Web API中使用OData的Action和Function
本篇体验OData的Action和Function功能。上下文信息参考"ASP.NET Web API基于OData的增删改查,以及处理实体间关系"。在本文之前,我存在的疑惑包括:
● 为什么需要OData的Action和Function功能?
● Action和Function之间有什么区别?
● 如何设置OData的的Action和Function功能?这中间有哪些惯例呢?
为某个Product添加Action
如果我们希望通过http://localhost:54714/odata/Products(1)/SomeActionName来实现在某个Product基础上,为Product的关联表ProductRating添加一条数据,该如何做到呢?
首先创建产品评论的一个模型:
public class ProductRating
{
public int ID { get; set; }
public int Rating { get; set; }
public int ProductID { get; set; }
public virtual Product Product { get; set; }
}
把模型添加到上下文中:
public class ProductsContext : DbContext
{
public ProductsContext()
: base("name=ProductsContext")
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbSet<ProductRating> Ratings { get; set; }
}
添加迁移并更新数据库:
Add-Migration "AddProductRating" -StartUpProjectName ProductService -ProjectName ProductService
Update-Database -StartUpProjectName ProductService -ProjectName ProductService
现在,需要在WebApiConfig.cs中的Register方法中,为Product的EDM添加一个Action。
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.Namespace = "ProductService"; builder.EntitySet<Product>("Products");//创建EntityDataModel(EDM)
builder.EntitySet<Supplier>("Suppliers"); //http://localhost/Products(1)/ProductService.Rate 注意需要在Web.config中添加配置,因为在IIS上不允许带点,否则会返回404
builder.EntityType<Product>()
.Action("Rate")//给EDM添加一个Action
.Parameter<int>("Rating"); //Rating作为参数在前后端传递 config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model:builder.GetEdmModel());
以上,
● 通过builder.Namespace定义了Action的命名空间为ProductService
● 通过Action方法给Product这个EDM定义了Rate这个Action
● 通过Parameter<T>方法定义了参数
这意味着:
● 我们发出的请求格式大致是:http://localhost:54714/odata/Products(1)/ProductService.Rate
● API的action方法中,action名称是Rate,可以从前端接受一个名称为Rating的键值
可问题还有:
● 前端如何把Rating这个参数传递出去呢?
● 后端又如何接受这个Rating参数呢?
来看后端控制器部分的action,在ProductsController中添加如下:
//这里的action名称Rate必须和EDM定义的时候保持一致
[HttpPost]
public async Task<IHttpActionResult> Rate([FromODataUri] int key, ODataActionParameters parameters)
{
//先验证
if(!ModelState.IsValid)
{
return BadRequest();
} //再取值
int rating = (int)parameters["Rating"]; //实施操作
db.Ratings.Add(new ProductRating
{
ProductID = key,
Rating = rating
}); //捕获异常
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
if (!ProductExists(key))
{
return NotFound();
}
else
{
throw;
}
} return StatusCode(HttpStatusCode.NoContent); }
可见,后端是通过ODataActionParameters来接受前端传来的变量Rating。
现在前端可以试着发出请求了:
POST http://localhost:54714/odata/Products(1)/ProductService.Rate
Body {"Rating":5}
我们把Rating变量放在了Body中,以json传递给后端。
可是,返回结果是: 404 Not Found
这是因为,IIS还不接受类似ProductService.Rate这样的写法,在Web.config添加如下配置:
<system.webServer>
<handlers>
...
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="/odata/*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
重新请求,返回:204 No Content
为Product集合添加Action
如果想为Products集合添加如下方法发出如下请求:http://localhost:54714/odata/Products/ProductService.MostExpensive
首先还是配置EDM:
builder.EntityType<Product>().Collection
.Function("MostExpensive")
.Returns<double>();
在ProductsController中添加如下Action:
[HttpGet]
public IHttpActionResult MostExpensive()
{
var product = db.Products.Max(x => x.Price);
return Ok(product);
}
前端请求:
GET http://localhost:54714/odata/Products/ProductService.MostExpensive
返回:
{
"@odata.context": "http://localhost:54714/odata/$metadata#Edm.Decimal",
"value": 18.2
}
和EDM模型无关,添加Function
当我们需要添加一个与EDM 模型无关的方法时候,就使用Function。
首先在WebApi.config中配置如下:
builder.Function("GetSalesTaxRate")
.Returns<double>()
.Parameter<int>("PostalCode");
在某个Controller中添加如下:
[HttpGet]
[ODataRoute("GetSalesTaxRate(PostalCode={postalCode})")]
public IHttpActionResult GetSalesTaxRate([FromODataUri] int postalCode)
{
double rate = 5.8;
return Ok(rate);
}
以上,ODataRoute设定路由规则。前端发出如下请求:
GET http://localhost:54714/odata/GetSalesTaxRate(PostalCode=10)
返回:
{
"@odata.context": "http://localhost:54714/odata/$metadata#Edm.Double",
"value": 5.8
}
总结:当需要针对某个EDM模型或EDM模型集合进行CRUD以外的操作,甚至涉及多个模型的操作使用Action,但添加和EDM模型无关的操作,使用Function。
在ASP.NET Web API中使用OData的Action和Function的更多相关文章
- ASP.NET Web API中使用OData
在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...
- 在ASP.NET Web API中使用OData
http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...
- [翻译]在ASP.NET Web API中通过OData支持查询和分页
OData可以通过形如http://localhost/Products?$orderby=Name这样的QueryString传递查询条件.排序等.你可以在任何Web API Controller中 ...
- 在ASP.NET Web API中使用OData的Containment
通常情况下,一个OData的EDM(Entity Data Model)在配置的时候定义了,才可以被查询或执行各种操作.比如如下: builder.EntitySet<SomeModel> ...
- 在ASP.NET Web API中使用OData的单例模式
从OData v4开始增加了对单例模式的支持,我们不用每次根据主键等来获取某个EDM,就像在C#中使用单例模式一样.实现方式大致需要两步: 1.在需要实现单例模式的导航属性上加上[Singleton] ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- ASP.NET Web API 中的异常处理(转载)
转载地址:ASP.NET Web API 中的异常处理
- 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化
谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...
- Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...
随机推荐
- JavaScript深入解读
JavaScript是运行在浏览器上的脚本语言.我们平时看到丰富多彩的网页,这要在很大程度上归功于JavaScript. 引子 学点儿历史 JavaScript在编程语言的阵营里也是老资格了.它诞生于 ...
- Mybatis 接口传入多个参数 xml怎么接收
mybatis 在接口上传入多个参数 1.如果传入的参数类型一样. Map<String, String> queryDkpayBindBankCidByOriBindAndBankCid ...
- python过滤 Kubernetes api数据
一.需求分析 Kubernetes endpoints api地址 http://ip地址:端口/api/v1/namespaces/default/endpoints services api地址 ...
- input标签的事件汇总
我在做一个注册时用到了,在网上查的,比较碎.就汇总了下, 1.onfocus 当input 获取到焦点时触发 2.onblur 当input失去焦点时触发,注意:这个事件触发的前提是已经获取了焦点 ...
- 《JavaScript 高级程序设计》第一章:简介
JavaScript 历史 JavaScript的诞生的主要是当时的 netspace 公司谋求为自己的浏览器 Navigator 添加一种脚本语言,以便在本地客户端进行一些行为操作,而这一功能的需求 ...
- 如何区分prometheus中Histogram和Summary类型的metrics?
要理解它们的区别,关键还是告业务应用. 但如何在学习时,如何区分呢? 有以下几个维度: histogram有bucket,summary在quatile. summary分位数是客户端计算上报,his ...
- JavaScript中变量的相互引用
http://www.jb51.net/article/23387.htm
- EntityFramework 系列:实体类配置-根据依赖配置关系和关联
EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理.为了方便理解,我们使用简化的实体A和B以及A.B ...
- spring applicationContext.xml中<beans>中属性概述
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w ...
- 转:Spring中事物管理
1.什么是事务? 事务是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事物具有四大特性ACID 说到事务,就不得不说其4大特性,主要如下 原子性:(atomicity) 原子性指的是事务是 ...