当前位置: 移动技术网 > IT编程>开发语言>.net > .NET Core开发日志之OData(Open Data Protocol)

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

2019年03月20日  | 移动技术网IT编程  | 我要评论

软件开发课程,600877资金流向,68use

简述

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

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网