ASP.Net Core + EF + OData V4核心Beta 2

在使用EF配置的ASP.NET Core上有一个相当基本的Web API项目,它可以正常使用Web API。 我正在关注这篇文章转换为使用Odata,我无法让它工作。

我有一个名为customer的父对象,带有2个子对象:Addresses和Person。 我已经播种了数据库,所以我可以看到那里有数据,而Odata端点看起来很好,因为当你启动项目时它会显示实体,odata / $ metadata会按预期显示EDM结构。

我目前唯一的问题是,当我导航到一个URL,例如/ odata / customers时,我收到一个空白屏幕。 在邮递员中,它返回404。

我已经梳理了Lucas的示例项目(我正在阅读的文章),并在网上进行了一些调查,并且看不出我做错了什么。

我确定这是简单/愚蠢的事情,但任何建设性的指导都欢迎:)

**编辑**为简单起见,删除了其他代码(并根据反馈)。 如果需要其他信息,请与我们联系。

干杯,

亚当

文件路径:Odata \ BookingsModelBuilder.cs

using System; using Microsoft.AspNet.OData.Builder; using Microsoft.OData.Edm; using Bookings_Server.OData.Models; namespace Bookings_Server { public class BookingsModelBuilder { public IEdmModel GetEdmModel(IServiceProvider serviceProvider) { var builder = new ODataConventionModelBuilder(serviceProvider); builder.EntitySet
("addresses") .EntityType .Filter() // Allow for the $filter Command .Count() // Allow for the $count Command .Expand() // Allow for the $expand Command .OrderBy() // Allow for the $orderby Command .Page() // Allow for the $top and $skip Commands .Select();// Allow for the $select Command; builder.EntitySet("customers") .EntityType .Filter() // Allow for the $filter Command .Count() // Allow for the $count Command .Expand() // Allow for the $expand Command .OrderBy() // Allow for the $orderby Command .Page() // Allow for the $top and $skip Commands .Select();// Allow for the $select Command; builder.EntitySet("people") .EntityType .Filter() // Allow for the $filter Command .Count() // Allow for the $count Command .Expand() // Allow for the $expand Command .OrderBy() // Allow for the $orderby Command .Page() // Allow for the $top and $skip Commands .Select();// Allow for the $select Command; return builder.GetEdmModel(); } } }

文件路径:EF \ DataContext.CS

 using Microsoft.EntityFrameworkCore; using Bookings_Server.OData.Models; namespace Bookings_Server.EF { public class DataContext : DbContext { public DataContext(DbContextOptions options) : base(options) { } public DbSet
Addresses { get; set; } public DbSet Customers { get; set; } public DbSet People { get; set; } public DbSet Tenants { get; set; } } }

文件路径:Controllers \ CustomersController.cs

 using System.Linq; using Microsoft.AspNetCore.Mvc; using Bookings_Server.EF; using Bookings_Server.OData.Models; using Microsoft.AspNet.OData; namespace Bookings_Server.OData.Controllers { [Produces("application/json")] public class CustomersController : ODataController { private readonly DataContext _context; public CustomersController(DataContext context) { _context = context; } // GET: odata/customers [EnableQuery(PageSize = 20)] public IQueryable Get() => _context.Customers.AsQueryable(); /* public IActionResult Get() { return Ok(_context.Customers.AsQueryable()); } */ } } 

文件路径:startup.cs

 using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.EntityFrameworkCore; using Microsoft.AspNet.OData.Extensions; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; namespace Bookings_Server { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, BookingsModelBuilder BookingsModelBuilder) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("cors"); // app.UseMvc(); // Added for Odata config app.UseMvc(routeBuilder => { routeBuilder.MapODataServiceRoute("ODataRoutes", "odata", BookingsModelBuilder.GetEdmModel(app.ApplicationServices)); }); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(options => options.AddPolicy("cors", builder => { builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); } )); var connection = @"Server=(localdb)\mssqllocaldb;Database=BookingsDB;Trusted_Connection=True;"; services.AddDbContext(options => options.UseSqlServer(connection)); // Add OData configuration services.AddOData(); services.AddTransient(); services.AddMvc().AddJsonOptions(opt => { opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; }); } } } 

好。 解决了这个问题。 这到底是愚蠢的。 我错过了CustomerContoller.cs上的装饰器

 [ODataRoute("customers")] 

和命名空间:

 using Microsoft.AspNet.OData.Routing; 

之后一切都开始正常。

 // GET: odata/customers [ODataRoute("customers")] [EnableQuery(PageSize = 20)] public IQueryable Get() => _context.Customers.AsQueryable(); 

其他信息: http : //odata.github.io/WebApi/03-03-attrribute-routing/

作为一种解决方法,您可以将更改直接应用于现有控制器,可以轻松地将此代码设置为Generic并添加到基本控制器,这将适用于现有控制器:

 [HttpGet] [EnableQuery] public async Task GetFilteredODataList(ODataQueryOptions q) { var skillsQuery = this._context.Skills.AsQueryable(); if (q?.Filter != null) { skillsQuery = q.Filter.ApplyTo(skillsQuery, new ODataQuerySettings()) as IQueryable; } return await skillsQuery.ToArrayAsync(); }