OData集成
介绍
在odata.org中OData定义为“一种开放协议允许使用简单或标准的方式创建和消费可查询和可交互的RESTful APIs”。你可以在ABP中使用OData。Abp.Web.Api.OData nuget包简化了它的使用。
安装
安装Nuget包
首先需要在我们的WebApi工程中安装Abp.OData nuget包:
Install-Package Abp.Web.Api.OData
设置模块依赖
我们的模块中需要设置AbpApiODataModule的依赖。示例:
[DependsOn(typeof(AbpWebApiODataModule))]
public class MyProjectWebApiModule : AbpModule
{
...
}
参见模块系统了解模块依赖。
配置实体
OData需要声明可以用做为OData资源的实体。我们应该在模块的PreInitialize方法中定义,如下所示:
[DependsOn(typeof(AbpWebApiODataModule))]
public class MyProjectWebApiModule : AbpModule
{
public override void PreInitialize()
{
var builder = Configuration.Modules.AbpWebApiOData().ODataModelBuilder; //Configure your entities here...
builder.EntitySet<Person>("Persons");
} ...
}
这里,我们获取ODataModelBuilder引用并设置Person实体。类似的,你可以使用EntitySet添加其他的实体。参见OData文档了解更多关于builder的信息。
创建控制器
Abp.Web.Api.OData nuget包包含AbpODataEntityController基类(扩展自标准的ODataControler)用来方便的创建你自己的控制器。创建Person实体OData终结点的实例如下:
public class PersonsController : AbpODataEntityController<Person>
{
public PersonsController(IRepository<Person> repository)
: base(repository)
{
}
}
非常简单!AbpODataEntityController的所有方法都是virtual的。这意味着,你可以重写Get、POST、Put、Patch、Delete和其他actions并添加自己的逻辑。
配置
Abp.Web.Api.OData使用常规配置自动调用HttpConfiguration.MapODataServiceRoute方法。如果需要,你可以设置Configuration.Modules.AbpWebApiOData().MapAction映射到自己的OData路径。
示例
这里,有一些请求上面定义的控制器的例子。假定应用运行在http://localhost:61482。我们将展示一些基本要素。因为OData是一个标准协议,你可以轻松的在网上找到更多高级的例子。
获取实体列表
获取所有的people。
Request
GET http://localhost:61842/odata/Persons
Response
{
"@odata.context":"http://localhost:61842/odata/$metadata#Persons","value":[
{
"Name":"Douglas Adams","IsDeleted":false,"DeleterUserId":null,"DeletionTime":null,"LastModificationTime":null,"LastModifierUserId":null,"CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":
},{
"Name":"John Nash","IsDeleted":false,"DeleterUserId":null,"DeletionTime":null,"LastModificationTime":null,"LastModifierUserId":null,"CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":
}
]
}
获取单个实体
获取Id=2的person。
Request
GET http://localhost:61842/odata/Persons(2)
Response
{
"@odata.context":"http://localhost:61842/odata/$metadata#Persons/$entity","Name":"John Nash","IsDeleted":false,"DeleterUserId":null,"DeletionTime":null,"LastModificationTime":null,"LastModifierUserId":null,"CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":
}
使用导航属性获取单个实体
获取Id=1的person并包含他的电话号码。
Request
GET http://localhost:61842/odata/Persons(1)?$expand=Phones
Response
{
"@odata.context":"http://localhost:61842/odata/$metadata#Persons/$entity","Name":"Douglas Adams","IsDeleted":false,"DeleterUserId":null,"DeletionTime":null,"LastModificationTime":null,"LastModifierUserId":null,"CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":,"Phones":[
{
"PersonId":,"Type":"Mobile","Number":"","CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":
},{
"PersonId":,"Type":"Mobile","Number":"","CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":
}
]
}
查询
这里,一个更高级的查询包含过滤、排序并获取前两个结果。
Request
GET http://localhost:61842/odata/Persons?$filter=Name eq 'Douglas Adams'&$orderby=CreationTime&$top=2
Response
{
"@odata.context":"http://localhost:61842/odata/$metadata#Persons","value":[
{
"Name":"Douglas Adams","IsDeleted":false,"DeleterUserId":null,"DeletionTime":null,"LastModificationTime":null,"LastModifierUserId":null,"CreationTime":"2015-11-07T20:12:39.363+03:00","CreatorUserId":null,"Id":
},{
"Name":"Douglas Adams","IsDeleted":false,"DeleterUserId":null,"DeletionTime":null,"LastModificationTime":null,"LastModifierUserId":null,"CreationTime":"2016-01-12T20:29:03+02:00","CreatorUserId":null,"Id":
}
]
}
OData支持分页,排序,过滤,投射等。参见它的文档了解更多信息。
创建新实体
在这个例子中,我们创建一个新person。
Request
POST http://localhost:61842/odata/Persons {
Name: "Galileo Galilei"
}
这里,“Content-Type”头为"application/json"。
Response
{
"@odata.context": "http://localhost:61842/odata/$metadata#Persons/$entity",
"Name": "Galileo Galilei",
"IsDeleted": false,
"DeleterUserId": null,
"DeletionTime": null,
"LastModificationTime": null,
"LastModifierUserId": null,
"CreationTime": "2016-01-12T20:36:04.1628263+02:00",
"CreatorUserId": null,
"Id":
}
如果我们再一次获取这个列表,我们就会看见这个新的person。我们也可以update或delete一个存在的实体,OData是支持的。
获取元数据
我们可以获取实体的元数据,如在本例中所示。
Request
GET http://localhost:61842/odata/$metadata
Response
<?xml version="1.0" encoding="utf-8"?> <edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx"> <edmx:DataServices> <Schema Namespace="AbpODataDemo.People" xmlns="http://docs.oasis-open.org/odata/ns/edm"> <EntityType Name="Person"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="Name" Type="Edm.String" Nullable="false" /> <Property Name="IsDeleted" Type="Edm.Boolean" Nullable="false" /> <Property Name="DeleterUserId" Type="Edm.Int64" /> <Property Name="DeletionTime" Type="Edm.DateTimeOffset" /> <Property Name="LastModificationTime" Type="Edm.DateTimeOffset" /> <Property Name="LastModifierUserId" Type="Edm.Int64" /> <Property Name="CreationTime" Type="Edm.DateTimeOffset" Nullable="false" /> <Property Name="CreatorUserId" Type="Edm.Int64" /> <Property Name="Id" Type="Edm.Int32" Nullable="false" /> <NavigationProperty Name="Phones" Type="Collection(AbpODataDemo.People.Phone)" /> </EntityType> <EntityType Name="Phone"> <Key> <PropertyRef Name="Id" /> </Key> <Property Name="PersonId" Type="Edm.Int32" /> <Property Name="Type" Type="AbpODataDemo.People.PhoneType" Nullable="false" /> <Property Name="Number" Type="Edm.String" Nullable="false" /> <Property Name="CreationTime" Type="Edm.DateTimeOffset" Nullable="false" /> <Property Name="CreatorUserId" Type="Edm.Int64" /> <Property Name="Id" Type="Edm.Int32" Nullable="false" /> <NavigationProperty Name="Person" Type="AbpODataDemo.People.Person"> <ReferentialConstraint Property="PersonId" ReferencedProperty="Id" /> </NavigationProperty> </EntityType> <EnumType Name="PhoneType"> <Member Name="Unknown" Value="0" /> <Member Name="Mobile" Value="1" /> <Member Name="Home" Value="2" /> <Member Name="Office" Value="3" /> </EnumType> </Schema> <Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm"> <EntityContainer Name="Container"> <EntitySet Name="Persons" EntityType="AbpODataDemo.People.Person" /> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx>
元数据用来研究这个服务。
示例工程
你可以在这里获取示例工程的源代码:https://github.com/aspnetboilerplate/sample-odata。