在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 ...
随机推荐
- python3转变exe的方法
python开发的代码可能在其他windows上并不能使用用,除非别人的环境中也有python. 下面是如何将python开发的东西转为exe格式 1.安装pyinstaller pip instal ...
- 【API】文件操作编程基础-CreateFile、WriteFile、SetFilePointer
1.说明 很多黑客工具的实现是通过对文件进行读写操作的,而文件读写操作实质也是对API函数的调用. 2.相关函数 CreateFile : 创建或打开文件或I/O设备.最常用的I/O设备如下:文件,文 ...
- linux C守护进程编写
linux编程-守护进程编写 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待 处理某些发生的事件.守护进程是一种很有用的进程. Linux的大多数服 ...
- WCF服务安全控制之netTcpBinding的用户名密码验证【转】
选择netTcpBinding WCF的绑定方式比较多,常用的大体有四种: wsHttpBinding basicHttpBinding netTcpBinding wsDualHttpBinding ...
- hadoop-2.7.2-HA安装笔记
配置方案如图 NN DN ZK ZKFC JN RM NM(任务管理器) HMaster Region Server Node1 1 1 1 1 1 Node2 1 1 1 1 1 1 1 Nod ...
- java代码分页
分页类 这个适用情况: 适用于前端页面已提供分页按钮样式的情况 分页规则: 首页,尾页,上页,下页 这四个按钮必定出现,中间分页动态生成5个 如:首 上 2 3 4 5 6 下 尾 public cl ...
- Asp.Net Mvc5 结合 SignalR2.0+ 实现消息交互简单例子
Nuget添加 SignalR包 1.构建一个MyHubServer服务端类 定义类的特性标签为 [HubName("chatHub")] public class MyHubSe ...
- 第一届CCF软件能力认证
1.相反数 问题描述 有 N 个非零且各不相同的整数.请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数). 输入格式 第一行包含一个正整数 N.(1 ≤ N ≤ 500). 第二行为 ...
- eaccelerator 完全手册:配置、控制、API接口
安装官方有很详细的文档 转自 http://www.enjoyphp.com/2010/eaccelerator-manual/ 配置选项 eaccelerator.shm_size指定 eAccel ...
- rabbitmq route
AMQP AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程 ...