在返回PageResult的odata webapi调用中,我从method参数中提取requestUri,操作过滤器术语,然后使用新的uri构造一个新的ODataQueryOptions对象。
(PageResult方法基于这篇文章: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options)
这是原始入境uri,其中包括%24inlinecount = allpages
http://localhost:59459/api/apiOrders/?%24filter=OrderStatusName+eq+'Started'&filterLogic=AND&%24skip=0&%24top=10&%24inlinecount=allpages&_=1376341370337
除了Request.GetInLineCount返回null之外,返回的数据一切正常。
由于客户端ui元素不知道记录总数,因此在客户端进行“终止”分页。
我在构建新的ODataQueryOptions对象时一定有问题。
请参阅下面的代码。任何帮助,将不胜感激。
我怀疑这篇文章可能包含一些线索https://stackoverflow.com/a/16361875/1433194,但我很难过。
public PageResult<OrderVm> Get(ODataQueryOptions<OrderVm> options)
{
var incomingUri = options.Request.RequestUri.AbsoluteUri;
//manipulate the uri here to suit the entity model
//(related to a transformation needed for enumerable type OrderStatusId )
//e.g. the query string may include %24filter=OrderStatusName+eq+'Started'
//I manipulate this to %24filter=OrderStatusId+eq+'Started'
ODataQueryOptions<OrderVm> options2;
var newUri = incomingUri; //pretend it was manipulated as above
//Reconstruct the ODataQueryOptions with the modified Uri
var request = new HttpRequestMessage(HttpMethod.Get, newUri);
//construct a new options object using the new request object
options2 = new ODataQueryOptions<OrderVm>(options.Context, request);
//Extract a queryable from the repository. contents is an IQueryable<Order>
var contents = _unitOfWork.OrderRepository.Get(null, o => o.OrderByDescending(c => c.OrderId), "");
//project it onto the view model to be used in a grid for display purposes
//the following projections etc work fine and do not interfere with GetInlineCount if
//I avoid the step of constructing and using a new options object
var ds = contents.Select(o => new OrderVm
{
OrderId = o.OrderId,
OrderCode = o.OrderCode,
CustomerId = o.CustomerId,
AmountCharged = o.AmountCharged,
CustomerName = o.Customer.FirstName + " " + o.Customer.LastName,
Donation = o.Donation,
OrderDate = o.OrderDate,
OrderStatusId = o.StatusId,
OrderStatusName = ""
});
//note the use of 'options2' here replacing the original 'options'
var settings = new ODataQuerySettings()
{
PageSize = options2.Top != null ? options2.Top.Value : 5
};
//apply the odata transformation
//note the use of 'options2' here replacing the original 'options'
IQueryable results = options2.ApplyTo(ds, settings);
//Update the field containing the string representation of the enum
foreach (OrderVm row in results)
{
row.OrderStatusName = row.OrderStatusId.ToString();
}
//get the total number of records in the result set
//THIS RETURNS NULL WHEN USING the 'options2' object - THIS IS MY PROBLEM
var count = Request.GetInlineCount();
//create the PageResult object
var pr = new PageResult<OrderVm>(
results as IEnumerable<OrderVm>,
Request.GetNextPageLink(),
count
);
return pr;
}
EDIT
所以纠正后的代码应该是
//create the PageResult object
var pr = new PageResult<OrderVm>(
results as IEnumerable<OrderVm>,
request.GetNextPageLink(),
request.GetInlineCount();
);
return pr;
EDIT
通过将Json转换应用于OrderVm类的OrderStatusId属性(枚举),避免了对控制器方法中枚举的字符串转换的需要
[JsonConverter(typeof(StringEnumConverter))]
public OrderStatus OrderStatusId { get; set; }
这消除了foreach循环。
答案 0 :(得分:0)
仅当客户通过$inlinecount查询选项请求时才会出现InlineCount。
在修改uri逻辑中,添加查询选项$inlinecount=allpages
(如果尚未存在)。
此外,您的代码中存在一个小错误。您正在创建的新ODataQueryOptions使用新的request
,与GetInlineCount调用中一样,您使用旧的Request
。它们不一样。
应该是,
var count = request.GetInlineCount(); // use the new request that your created, as that is what you applied the query to.