在ASP.NET Core WebAPI中获取OData计数 [英] Getting OData Count in ASP.NET Core WebAPI

查看:240
本文介绍了在ASP.NET Core WebAPI中获取OData计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用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-Typeapplication/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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆