在ASP.NET Core WebAPI中获取OData计数 [英] Getting OData Count in ASP.NET Core WebAPI
问题描述
使用Hassan Habib的 Supercharging的示例代码带有OData的ASP.NET Core API 博客文章,我能够使用$count=true
的OData查询来获取记录数:
Using the sample code from Hassan Habib's Supercharging ASP.NET Core API with OData blog post, I am able to get the record count using an OData query of $count=true
:
需要什么配置才能将响应对象包装在OData context
中,以便显示@odata.count
属性?
What needs to be configured to get the response object to be wrapped in an OData context
so that the @odata.count
property will show?
在我自己的ASP.NET Core Web API项目中,我无法使用简单的$count
参数,也不知道为什么.
In my own ASP.NET Core web API project, I cannot get the simple $count
parameter to work and I have no idea why.
使用Hassan的示例代码,响应JSON包装在OData context
中,有效负载(IEnumerable<Student>
对象)在JSON响应的value
属性中.在我的项目中,OData context
包装器不存在.我的代码从不返回OData context
,它仅返回IEnumerable<T>
类型的有效载荷对象:
With Hassan's sample code, the response JSON is wrapped in an OData context
and the payload (an IEnumerable<Student>
object) is in the value
property of the JSON response. In my project, the OData context
wrapper does not exist; my code never returns OData context
, it only returns the payload object of type IEnumerable<T>
:
我还注意到在示例项目中,响应标头中的Content-Type
是application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
,而在我的项目中,它只是application/json; charset=utf-8
.我在这两个项目中都没有看到可控制此设置的设置,因此我假设Microsoft.AspNetCore.Odata
NuGet包在正确配置后正在神奇地更改响应.
I've also noticed that the Content-Type
in the response header is application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
in the sample project, where as it is simply application/json; charset=utf-8
in my project. I don't see any setting that controls this in either project, so I'm assuming the Microsoft.AspNetCore.Odata
NuGet package is magically changing the response when it's configured properly.
我的项目还使用.NET Core 2.2(从2.1升级),与Hassan示例项目相同的NuGet软件包版本,以及StartUp.cs
类中的所有相同设置...尽管我的StartUp.cs
是方式更为复杂(因此,我不在此处发布内容的原因.)
My project is also using .NET Core 2.2 (Upgraded from 2.1), all the same versions of NuGet packages as Hassan's sample projects, and all the same settings in the StartUp.cs
class... although my StartUp.cs
is way more complicated (hence the reason I'm not posting it's content here.)
推荐答案
当我将[Route("api/[controller]")]
和[ApiController]
与startup.cs一起使用时,我可以重现您的问题,如下所示:
I could reproduce your issue when i use [Route("api/[controller]")]
and [ApiController]
with the startup.cs like below:
app.UseMvc(routeBuilder =>
{
routeBuilder.Expand().Select().Count().OrderBy().Filter();
routeBuilder.EnableDependencyInjection();
});
要解决此问题,请确保已建立一个私有方法来在现有数据模型(在这种情况下为OData模型)与EDM之间进行握手.
To fix it,be sure you have built a private method to do a handshake between your existing data models (OData model in this case) and EDM.
这是一个简单的演示:
1.Controller(对Route
属性和ApiController
属性的注释):
1.Controller(comment on Route
attribute and ApiController
attribute):
//[Route("api/[controller]")]
//[ApiController]
public class StudentsController : ControllerBase
{
private readonly WSDbContext _context;
public StudentsController(WSDbContext context)
{
_context = context;
}
// GET: api/Students
[HttpGet]
[EnableQuery()]
public IEnumerable<Student> Get()
{
return _context.Students;
}
}
//[Route("api/[controller]")]
//[ApiController]
public class SchoolsController : ControllerBase
{
private readonly WSDbContext _context;
public SchoolsController(WSDbContext context)
{
_context = context;
}
// GET: api/Schools
[HttpGet]
[EnableQuery()]
public IEnumerable<School> Get()
{
return _context.Schools;
}
2.Startup.cs():
2.Startup.cs():
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvcCore(action => action.EnableEndpointRouting = false);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
var connection = @"Server=(localdb)\mssqllocaldb;Database=WSDB;Trusted_Connection=True;ConnectRetryCount=0";
services.AddDbContext<WSDbContext>(options => options.UseSqlServer(connection));
services.AddOData();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc(routeBuilder =>
{
routeBuilder.Expand().Select().Count().OrderBy().Filter();
routeBuilder.MapODataServiceRoute("api", "api", GetEdmModel());
});
}
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<Student>("Students");
builder.EntitySet<Student>("Schools");
return builder.GetEdmModel();
}
}
这篇关于在ASP.NET Core WebAPI中获取OData计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!