【发布时间】:2018-09-27 14:23:06
【问题描述】:
在配置了 EF 的 ASP.NET Core 上有一个相当基本的 Web API 项目,该项目可以正常使用 Web API。我正在关注this 文章以转换为使用 Odata,但我无法让它正常工作。
我有一个名为 customer 的父对象,它有 2 个子对象:Addresses 和 Person。我已为数据库播种,因此我可以看到那里有数据,并且 Odata 端点看起来不错,因为当您启动项目时,它会显示实体,而 odata/$metadata 会按预期显示 EDM 结构。
我目前唯一遇到的问题是,当我导航到 /odata/customers 等 URL 时,我收到一个空白屏幕。在邮递员中它返回 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<Address>("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<Customer>("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<Person>("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<DataContext> options) : base(options) { }
public DbSet<Address> Addresses { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Person> People { get; set; }
public DbSet<Tenant> 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<Customer> 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<EF.DataContext>(options => options.UseSqlServer(connection));
// Add OData configuration
services.AddOData();
services.AddTransient<BookingsModelBuilder>();
services.AddMvc().AddJsonOptions(opt =>
{
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
opt.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
}
}
}
【问题讨论】:
-
1.请移除除 Startup 和控制器之外的所有模型。 (太多的代码吓跑了用户) 2. 您需要添加 OData
routeBuilder.Count().Filter().OrderBy().Expand().Select().MaxTop(null);允许的设置 3. 我遇到了同样的问题,您可以在另一个问题中看到解决方法我 asked 看看我的控制器 -
感谢您的反馈。我会编辑和清理(如果需要,可以添加回来)。也许我做得不对,但是 Odata 设置是在顶部的 BookingsModelBuilder 中定义的,并通过 Startup.cs 调用
-
我会看看这是否可行,我想我曾经尝试过,但我仍然能够通过扩展其他实体来访问它们
标签: c# entity-framework odata asp.net-core-webapi