在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中配置如下:
在某个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的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 分享一百多套开发视频教程的下载地址(转)
- 下一篇: 信息树和XML文件的遍历及XML文件的应