首页 > 开发 > .Net > 正文

.NET Core开发日志之OData(Open Data Protocol)

2019-10-27 12:20:14
字体:
来源:转载
供稿:网友

简述

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",        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",        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,这样应该能减少许多不必要的代码工作。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对CuoXin错新网的支持。


注:相关教程知识阅读请移步到ASP.NET教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表