分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

.NET Core开发日志——OData

发布时间:2023-09-06 02:32责任编辑:郭大石关键词:.NET

简述

OData,即Open Data Protocol,是由微软在2007年推出的一款开放协议,旨在通过简单、标准的方式创建和使用查询式及交互式RESTful API。

类库

在.NET Core中想要使用OData功能的话需要添加Microsoft.AspNetCore.OData包。

dotnet add package Microsoft.AspNetCore.OData

准备模型类

public class Address{ ???public string City { get; set; } ???public string Street { get; set; }}public enum Category{ ???Book, ???Magazine, ???EBook}public class Press{ ???public int Id { get; set; } ???public string Name { get; set; } ???public string Email { get; set; } ???public Category Category { get; set; }}public class Book{ ???public int Id { get; set; } ???public string ISBN { get; set; } ???public string Title { get; set; } ???public string Author { get; set; } ???public decimal Price { get; set; } ???public Address Address { get; set; } ???public Press Press { get; set; }}

创建Edm模型

OData使用EDM,即Entity Data Model来描述数据的结构。在Startup文件中添加创建方法。

private static IEdmModel GetEdmModel(){ ???var builder = new ODataConventionModelBuilder(); ???builder.EntitySet<Book>("Books"); ???builder.EntitySet<Press>("Presses"); ???return builder.GetEdmModel();}

注册OData服务

在Startup文件的ConfigureServices方法里注册OData服务。

services.AddOData();services.AddMvc(options => ???{ ???????options.EnableEndpointRouting = false; ???}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

这里要注意的是在.NET Core 2.2里,默认已经有终结点,所以要使用OData的终结点的话需要将默认选项禁用掉。

注册OData终结点

同样在Startup文件里,在其Configure方法内将原来的注册路由内容改为注册OData的终结点。

app.UseMvc(b =>{ ???b.MapODataServiceRoute("odata", "odata", GetEdmModel());});

显示元数据

运行程序后访问https://localhost:5001/odata/$metadata地址,可以看到所有可用模型的元数据。

<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0"> ???<edmx:DataServices> ???????<Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="Default"> ???????????<EntityType Name="Book"> ???????????????<Key> ???????????????????<PropertyRef Name="Id"/> ???????????????</Key> ???????????????<Property Name="Id" Type="Edm.Int32" Nullable="false"/> ???????????????<Property Name="ISBN" Type="Edm.String"/> ???????????????<Property Name="Title" Type="Edm.String"/> ???????????????<Property Name="Author" Type="Edm.String"/> ???????????????<Property Name="Price" Type="Edm.Decimal" Nullable="false"/> ???????????????<Property Name="Address" Type="Default.Address"/> ???????????????<NavigationProperty Name="Press" Type="Default.Press"/> ???????????</EntityType> ???????????<EntityType Name="Press"> ???????????????<Key> ???????????????????<PropertyRef Name="Id"/> ???????????????</Key> ???????????????<Property Name="Id" Type="Edm.Int32" Nullable="false"/> ???????????????<Property Name="Name" Type="Edm.String"/> ???????????????<Property Name="Email" Type="Edm.String"/> ???????????????<Property Name="Category" Type="Default.Category" Nullable="false"/> ???????????</EntityType> ???????????<ComplexType Name="Address"> ???????????????<Property Name="City" Type="Edm.String"/> ???????????????<Property Name="Street" Type="Edm.String"/> ???????????</ComplexType> ???????????<EnumType Name="Category"> ???????????????<Member Name="Book" Value="0"/> ???????????????<Member Name="Magazine" Value="1"/> ???????????????<Member Name="EBook" Value="2"/> ???????????</EnumType> ???????????<EntityContainer Name="Container"> ???????????????<EntitySet Name="Books" EntityType="Default.Book"> ???????????????????<NavigationPropertyBinding Path="Press" Target="Presses"/> ???????????????</EntitySet> ???????????????<EntitySet Name="Presses" EntityType="Default.Press"/> ???????????</EntityContainer> ???????</Schema> ???</edmx:DataServices></edmx:Edmx>

创建Controller

本文实例中不考虑数据库的操作,故而使用hard code方式构建必要的模型对象。

public class BooksController : ODataController{ ???private static IList<Book> Books {get; set;} ???public BooksController() ???{ ???????Books = new List<Book> ???????{ ???????????new Book ???????????{ ???????????????Id = 1, ???????????????ISBN = "111-0-321-56789-1", ???????????????Title = "Calculus", ???????????????Price = 66.6m, ???????????????Address = new Address ???????????????{ ???????????????????City = "Shanghai", ???????????????????Street = "Beijin Xi Road" ???????????????}, ???????????????Press = new Press ???????????????{ ???????????????????Id = 1, ???????????????????Name = "Shanghai Tongji", ???????????????????Category = Category.Book ???????????????} ???????????}, ???????????new Book ???????????{ ???????????????Id = 2, ???????????????ISBN = "222-2-654-00000-2", ???????????????Title = "Linear Algebra", ???????????????Price = 53.2m, ???????????????Address = new Address ???????????????{ ???????????????????City = "Shanghai", ???????????????????Street = "Beijin Dong Road" ???????????????}, ???????????????Press = new Press ???????????????{ ???????????????????Id = 2, ???????????????????Name = "Shanghai Fudan", ???????????????????Category = Category.EBook ???????????????} ???????????} ???????????????????}; ??????} ???[EnableQuery] ???public IActionResult Get() ???{ ???????return Ok(Books); ???} ???[EnableQuery] ???public IActionResult Get(int key) ???{ ???????return Ok(Books.FirstOrDefault(b => b.Id == key)); ???}}

EnableQuery特性在需要高级查询的场景时必须添加。

查询

加入Controller之后,访问https://localhost:5001/odata/Books地址,可得到所有Book数据。

{ ???"@odata.context": "https://localhost:5001/odata/$metadata#Books", ???"value": [ ???????{ ???????????"Id": 1, ???????????"ISBN": "111-0-321-56789-1", ???????????"Title": "Calculus", ???????????"Author": null, ???????????"Price": 66.6, ???????????"Address": { ???????????????"City": "Shanghai", ???????????????"Street": "Beijin Xi Road" ???????????} ???????}, ???????{ ???????????"Id": 2, ???????????"ISBN": "222-2-654-00000-2", ???????????"Title": "Linear Algebra", ???????????"Author": null, ???????????"Price": 53.2, ???????????"Address": { ???????????????"City": "Shanghai", ???????????????"Street": "Beijin Dong Road" ???????????} ???????} ???]}

访问https://localhost:5001/odata/Books(1)地址,可得到key值为1的Book数据。

{ ???"@odata.context": "https://localhost:5001/odata/$metadata#Books/$entity", ???"Id": 1, ???"ISBN": "111-0-321-56789-1", ???"Title": "Calculus", ???"Author": null, ???"Price": 66.6, ???"Address": { ???????"City": "Shanghai", ???????"Street": "Beijin Xi Road" ???}}

高级查询

如果想要使用OData查询的高级功能,可以在注册终结点时额外加上相应的配置。

app.UseMvc(b =>{ ???b.Select().Expand().Filter().OrderBy().MaxTop(100).Count(); ???b.MapODataServiceRoute("odata", "odata", GetEdmModel());});

访问网址时加上所需的查询内容:
https://localhost:5001/odata/Books?$select=Id,Title

{ ???"@odata.context": "https://localhost:5001/odata/$metadata#Books(Id,Title)", ???"value": [ ???????{ ???????????"Id": 1, ???????????"Title": "Calculus" ???????}, ???????{ ???????????"Id": 2, ???????????"Title": "Linear Algebra" ???????} ???]}

如果想要按特定条件过滤数据内容的话也很容易:
https://localhost:5001/odata/Books?$filter=Price%20le%2060

{ ???"@odata.context": "https://localhost:5001/odata/$metadata#Books", ???"value": [ ???????{ ???????????"Id": 2, ???????????"ISBN": "222-2-654-00000-2", ???????????"Title": "Linear Algebra", ???????????"Author": null, ???????????"Price": 53.2, ???????????"Address": { ???????????????"City": "Shanghai", ???????????????"Street": "Beijin Dong Road" ???????????} ???????} ???]}

总结

不难看出,OData的真正魅力在于其对那些高级查询功能的支持,所以在创建RESTful API时,不妨考虑使用OData,这样应该能减少许多不必要的代码工作。

.NET Core开发日志——OData

原文地址:https://www.cnblogs.com/kenwoo/p/10360260.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved