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

简述

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(Open Data Protocol) 的全部内容, 来源链接: utcz.com/z/312793.html

回到顶部