ASP.NET Core OData Part 1

栏目: IT技术 · 发布时间: 5年前

内容简介:ODatais anIt is surprising that not many people know about OData, also, there are some caveats to it and not much documentation on using it with ASP.NET Core, so I decided to write a few posts on the subject. Here is the first!Let’s pretend you have a doma

Introduction

ODatais an open standard for making an object-oriented domain model available as an HTTP REST interface.In a nutshell, it provides a specification for returning domain models as result of HTTP requests, querying them over the URL and even creating functions and actions over the domain model. In what .NET Core is concerned, it is a way by which you can expose your Entity Framework Core – or any other ORM that has a LINQ interface - to the web, without writing too much boilerplate code, as an ASP.NET Core Web API.

It is surprising that not many people know about OData, also, there are some caveats to it and not much documentation on using it with ASP.NET Core, so I decided to write a few posts on the subject. Here is the first!

Setting Up

Let’s pretend you have a domain model with just two classes, Parent and Child :

ASP.NET Core OData Part 1

We should also have an Entity Framework Core context that exposes them:

public class ParentChildContext : DbContext
{
public ParentChildContext(DbContextOptions options) : base(options) { }
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Children { get; set; }
}

I won’t go into details as to explain this, I’m pretty sure you all know about Entity Framework Core contexts! Just make sure you add a reference to the Microsoft.EntityFrameworkCore NuGet package, or, if you’re using SQL Server, Microsoft.EntityFrameworkCore.SqlServer . Now register your context to the DI framework, in the ConfigureServices method:

services.AddDbContext<ParentChildContext>(options =>
{
options.UseSqlServer(“<connection string>”);
});

In your ASP.NET Core’s project you need to add a reference to the Microsoft.AspNetCore.OData NuGet package. This includes the server-side implementation of OData version 4 for ASP.NET Core.

You need to add its required services in the ConfigureServices method:

services.AddOData();

This registers the services, but now we need to add an endpoint for an actual domain model. ASP.NET Core OData now supports endpoint routing, so everything can be done smoothly:

app.UseEndpoints(endpoints =>
{
    endpoints.MapODataRoute("odata", "odata", GetEdmModel(app.ApplicationServices));
});

We registered this endpoint with name odata (first parameter) and also with the same prefix (second parameter), you can happily change this. As you can see, in this route, we are returning an EDM Data Model . We build one as this:

private static IEdmModel GetEdmModel(IServiceProvider serviceProvider)
{
var builder = new ODataConventionModelBuilder(serviceProvider);
builder.EntitySet<Parent>("Parents");
builder.EntitySet<Child>("Children");
return builder.GetEdmModel();
}

One thing that you’ll notice is that this is a conventions -based model builder, ODataConventionModelBuilder . this one takes care of some things for you, such as inferring the id property for each entity, that’s why you don’t have to explicitly state it. If your entity has an id property with a funny name, other than Id or EntityId , then you will need to specify it:

builder
.EntitySet<Parent>(“Parents”)
.EntityType
.HasKey(x => x.Id);

There is no need to specify the other properties, because they are all inferred automatically too from the generic parameter.

Do keep in mind the entity set name that you give, it is common to have a pluralized form of the entity name, but it is not required.

Now we need to create a controller that exposes this. At the very least, we will need two methods:

[ODataRoutePrefix("Parents")]
public class ParentController : ODataController
{
private ParentChildContext _ctx;

public ParentController(ParentChildContext ctx)
{
this._ctx = ctx;
}

[ODataRoute]
public IQueryable<Parent> Get()
{
return this._ctx.Parents.AsQueryable();
}

[ODataRoute("{id}")]
public Parent Get([FromODataUri] int id)
{
return this._ctx.Parents.Find(id);
}
}

This controller is specific to the Parents entity set, so, if you wish, you need to have another one for the Children . This is specified in the [ ODataRoutePrefix ] attribute.

Also notice how we are returning IQueryable<Parent> from the Get action method that does not take parameters and a single Parent from the other. You can also declare IActionResult or ActionResult<T> :

[ODataRoute]
public IActionResult Get()
{
return this.Ok(this._ctx.Parents.AsQueryable());
}
//alternative
[ODataRoute]
public ActionResult<IQueryable<Parent>> Get()
{
return this.Ok(this._ctx.Parents.AsQueryable());
}

The latter, the one that uses ActionResult<T> , has some advantages, which you can read about here .

And, of course, all of the methods can be made asynchronous too:

[ODataRoute]
public async Task<IQueryable<Parent>> Get()
{
return await this._ctx.Parents.ToListAsync();
}

[ODataRoute("{id}")]
public async Task<Parent> Get([FromODataUri] int id)
{
return await this._ctx.Parents.FindAsync(id);
}

We will see a problem with the implementation of the first method in the next post.

Now, the first method, the one without parameters, returns all of the entities in the database, and the second, as one would expect, returns possibly one from its id property.

Conclusion

We’re all done here, so we can now access the endpoints we just created, try to navigate to the following URLs:

  • /odata: returns information about the exposed entity sets ( Parents and Children )

ASP.NET Core OData Part 1

  • / odata/parents –> ParentController.Get() : returns all records for the Parent entity

  • /odata/parents(1)–> ParentController.Get(1) : returns possibly one record, if it exists in the database for the given primary key of the Parent entity

This is the very basics, in the future posts we will explore other options, such as querying over the URL and creating functions and actions.

References

You can find more information in the following pages:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

探索需求

探索需求

章柏幸、王媛媛、谢攀、杰拉尔德・温伯格、唐纳德・高斯 / 章柏幸、王媛媛、谢攀 / 清华大学出版社 / 2004-7-1 / 39.00元

本书将与您一起寻找"什么是客户真正想要的"这一问题的答案。 本书着眼于系统设计之前的需求过程,它是整个开发过程(如何设计人们想要的产品和系统)中最有挑战性的那部分。通过对一些需求分析中的常见误区和问题的分析和讨论,从和客户沟通开始,深入研究一些可能的需求,澄清用户和开发者期望值,最终给出了能够大幅度提高项目成功几率的一些建议方法。 本书由该领域内公认的两位作者合著,搜集了他们在大大小小......一起来看看 《探索需求》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码