[英]Items count in OData v4 WebAPI response
如何返回 OData v4 HTTP 响应中的项目数?
我需要这个数字来分页,所以它应该是过滤后的项目数,但在“跳过”和“顶部”之前。
I already tried passing '$inlinecount=allpages' and '$count=true' parameters in query options in url ( https://damienbod.wordpress.com/2014/06/13/web-api-and-odata-v4- query-functions-and-attribute-routing-part-2/ - “Example of $count”),但我来自 WebAPI 的响应始终只有查询结果(集合) - 整个响应如下所示:
[
{
"Name":"name1",
"age":5
},
{
"Name":"name2",
"age":15
}
]
响应中没有像“odata.count”这样的东西。
我还尝试在我的 WebAPI controller 操作中返回 PageResult 而不是 IQueryable(如此处所述: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata- query-options#server-paging ),但 Request.GetInlineCount() 已弃用,其值始终为 null。
有任何想法吗?
[更新]我刚刚在这里发现了同样的问题: WebApi with Odata NextPage and Count not appearing in the JSON response and 我删除了 [EnableQuery] 属性,现在我的响应看起来像:
{
"Items":
[
{
"Name":"name1",
"age":5
},
{
"Name":"name2",
"age":15
}
],
"NextPageLink":null,
"Count":null
}
但“计数”始终是 null。 :(
public PageResult<People> Get(ODataQueryOptions<People> queryOptions) { var query = _context.People.OrderBy(x => x.SomeProperty); var queryResults = (IQueryable<People>)queryOptions.ApplyTo(query); long cnt = 0; if (queryOptions.Count.= null) cnt = long.Parse(Request.Properties["System.Web.OData.TotalCount"];ToString()), return new PageResult<People>(queryResults, null; cnt); }
它工作正常,但我仍然不知道为什么我必须使用这样的解决方法。
供将来参考(OData v4):
首先, $inlinecount
在OData v4
不支持,所以你应该使用$count=true
。
其次,如果你有一个普通的ApiController
并且你返回类似IQueryable<T>
的类型,那么你可以将count
属性附加到返回的结果:
using System.Web.OData;
using System.Web.OData.Query;
using System.Web.OData.Extensions;
//[EnableQuery] // -> If you enable globally queries does not require this decorator!
public IHttpActionResult Get(ODataQueryOptions<People> queryOptions)
{
var query = _peopleService.GetAllAsQueryable(); //Abstracted from the implementation of db access. Just returns IQueryable<People>
var queryResults = (IQueryable<People>)queryOptions.ApplyTo(query);
return Ok(new PageResult<People>(queryResults, Request.ODataProperties().NextLink, Request.ODataProperties().TotalCount));
}
注意:
ApiController
不支持OData功能,因此您不能使用count
或$metadata
。 如果您选择使用简单的ApiController
则上面的方法是您应该用来返回count
属性的方法。
要完全支持OData功能,您应该通过以下方式实现ODataController
:
PeopleController.cs
using System.Web.OData;
using System.Web.OData.Query;
public class PeopleController : ODataController
{
[EnableQuery(PageSize = 10, AllowedQueryOptions = AllowedQueryOptions.All)]
public IHttpActionResult Get()
{
var res = _peopleService.GetAllAsQueryable();
return Ok(res);
}
}
App_Start \\ WebApiConfig.cs
public static void ConfigureOData(HttpConfiguration config)
{
//OData Models
config.MapODataServiceRoute(routeName: "odata", routePrefix: null, model: GetEdmModel(), batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
}
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder
{
Namespace = "Api",
ContainerName = "DefaultContainer"
};
builder.EntitySet<People>("People").EntityType.HasKey(item => item.Id); //I suppose the returning list have a primary key property(feel free to replace the Id key with your key like email or whatever)
var edmModel = builder.GetEdmModel();
return edmModel;
}
然后以这种方式访问您的OData Api(示例):
编码的uri:
http://localhost:<portnumber>/People/?%24count=true&%24skip=1&%24top=3
解码:
http://localhost:<portnumber>/People/?$count=true&$skip=1&$top=3
参考文献:
这就是我在oData v4中使用的:
Request.ODataProperties().NextLink,
Request.ODataProperties().TotalCount
请您访问https://github.com/OData/ODataSamples/blob/master/Scenarios/TripPin,查看示例服务TripPin web api实现。 您可以按照机场控制器中的代码和代码http://services.odata.org/TripPinWebApiService/Airports的服务进行操作?$ count = true可以正确返回计数。
这也可以通过动作过滤器实现:
/// <summary>
/// Use this attribute whenever total number of records needs to be returned in the response in order to perform paging related operations at client side.
/// </summary>
public class PagedResultAttribute: ActionFilterAttribute
{
/// <summary>
///
/// </summary>
/// <param name="actionExecutedContext"></param>
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
if (actionExecutedContext.Response != null)
{
dynamic responseContent=null;
if (actionExecutedContext.Response.Content != null)
responseContent = actionExecutedContext.Response.Content.ReadAsAsync<dynamic>().Result;
var count = actionExecutedContext.Response.RequestMessage.ODataProperties().TotalCount;
var res = new PageResult<dynamic>() {TotalCount=count,Items= responseContent };
HttpResponseMessage message = new HttpResponseMessage();
message.StatusCode = actionExecutedContext.Response.StatusCode;
var strMessage = new StringContent(JsonConvert.SerializeObject(res), Encoding.UTF8, "application/json");
message.Content = strMessage;
actionExecutedContext.Response = message;
}
}
}
自定义PageResult类是:
public class PageResult<T>
{
public long? TotalCount { get; set; }
public T Items { get; set; }
}
用法:
[PagedResult]
[EnableQuery()]
如果您使用的是 OData 常规路由,则当您的路由不为 odata 所知时,不会返回 $odata.count。 添加 'app.UseODataRouteDebug();' 到您的 ConfigureServices 方法,然后调用“https://localhost:5001/$odata”。 如果您的路由不在 OData 路由表中,则 OData 不知道您的路由,并且您没有为要包含在 OData 常规路由中的 controller 和 EDM 类型使用正确的命名约定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.