Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
224 views
in Technique[技术] by (71.8m points)

c# - Web API OData V3 `$inlinecount` fails

I am using the out of the box ValuesController in a ASP.NET Web API application

 public class ValuesController : ApiController
 {
     // GET api/values
     [Queryable(PageSize = 1)]
     public IQueryable<string> Get()
     {
         return new string[] { "value1", "value2", "value3", "value4", "value5" }.AsQueryable();
     }
 }

When I get http://localhost/api/values?$inlinecount=allpages

This is the response

<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>value1</string>
</ArrayOfString>

I have uncommented config.EnableQuerySupport();

Filtering, sorting work fine.

If I try get http://localhost/api/values?$inlinecount=XXXXX I get an exception, so it seems the Web API application knows about inlinecount

<Message>The query specified in the URI is not valid.</Message>
<ExceptionMessage>'xxx' is not a valid value for $inlinecount.</ExceptionMessage> 
<ExceptionType>Microsoft.Data.OData.ODataException</ExceptionType>

I definitely have the Microsoft.AspNet.WebApi.OData package - here is the output of the Package Manager Console

PM> Install-Package Microsoft.AspNet.WebApi.OData 
Attempting to resolve dependency 'Microsoft.Net.Http (= 2.0.20710.0 && < 2.1)'.
Attempting to resolve dependency 'Microsoft.AspNet.WebApi.Client (= 4.0.20710.0 && < 4.1)'.
Attempting to resolve dependency 'Newtonsoft.Json (= 4.5.6)'.
Attempting to resolve dependency 'Microsoft.AspNet.WebApi.Core (= 4.0.20710.0 && < 4.1)'.
Attempting to resolve dependency 'Microsoft.Data.OData (= 5.2.0 && < 5.3.0)'.
Attempting to resolve dependency 'System.Spatial (= 5.2.0)'.
Attempting to resolve dependency 'Microsoft.Data.Edm (= 5.2.0)'.
'Microsoft.AspNet.WebApi.OData 4.0.0' already installed.
WebServicesProject already has a reference to 'Microsoft.AspNet.WebApi.OData 4.0.0'.

Any suggestions?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Great question.

$inlinecount out of the box only works when you're sending back OData responses. The reason for this is that OData defines special fields in the data that XML and JSON don't define. So in OData a response might look like this:

{
  "odata.metadata":"http://localhost:12345/odata/$metadata#Customers",
  "odata.count":"4",
  "value":[ ... ]
}

Notice the wrapper with the "odata.count" property. This is different from the way the default XML and JSON formatters write out data because they don't have wrappers for this additional information. So other formatters are by default unchanged.

Now you have several options:

You could choose to use the OData format. For this, you'll want to follow the instructions in this blog post:

http://blogs.msdn.com/b/webdev/archive/2013/01/29/getting-started-with-asp-net-webapi-odata-in-3-simple-steps.aspx

You could also choose to instead return a PageResult<T>. This looks like this:

public PageResult<Customer> Get(ODataQueryOptions<Customer> queryOptions)
{
    IQueryable results = queryOptions.ApplyTo(_customers.AsQueryable());
    return new PageResult<Customer>(results as IEnumerable<Customer>, Request.GetNextPageLink(), Request.GetInlineCount());
}

This should work fine for OData, JSON, and XML by adding a wrapper object for XML and JSON that can include the Count and the next page link.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...