OData queries and types other than IQueryable in A

2020-07-17 15:55发布

问题:

I am building an ASP.NET Web API application that returns an Atom or an RSS feed. To do this, it builds a System.ServiceModel.Syndication.SyndicationFeed and a custom MediaTypeFormatter is responsible for handling the HTTP Accept Header, converting the SyndicationFeed to either an Atom10FeedFormatter or an Rss20FeedFormatter, and streaming the result to the response stream. So far, so good.

My controller looks something like this:

    public class FeedController : ApiController
    {
        public HttpResponseMessage Get()
        {
            FeedRepository feedRepository = new FeedRepository();
            HttpResponseMessage<SyndicationFeed> successResponseMessage = new HttpResponseMessage<SyndicationFeed>(feedRepository.GetSyndicationFeed());
            return successResponseMessage;
        }
    }

What I would like to do is make use of the built-in OData querying to filter my feed, but changing the return type of the Get() method to IQueryable<SyndicationFeed> obviously will not work since a SyndicationFeed does not implement IQueryable.

Is there a way to use the built in OData querying on the IEnumerable<SyndicationItem> property on the SyndicationFeed?

回答1:

This question is no longer relevant, since Microsoft remove the rudimentary support for OData querying that was in the Beta build of Web API.

A future version will include more complete OData support. There is an early build of this available via CodePlex and NuGet and there are more details here: http://blogs.msdn.com/b/alexj/archive/2012/08/15/odata-support-in-asp-net-web-api.aspx



回答2:

The System.Linq namespace provides an extension method named AsQueryable to the IEnumerable interface. Your code would look along the lines of this:

public class FeedController : ApiController
{
    public IQueryable<SyndicationFeed> Get()
    {
        FeedRepository feedRepository = new FeedRepository();

        //TODO: Make sure your property handles empty/null results:
        return feedRepository.GetSyndicationFeed()
                   .YourEnumerableProperty.AsQueryable();
    }
}


回答3:

You don't have to return IQuerable from controller when working with OData. Check "Invoking Query Options Directly" section at https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options

For your case it will looks like:

public SyndicationFeed Get(ODataQueryOptions<SyndicationItem> opts)
{
    var settings = new ODataValidationSettings();

    opts.Validate(settings);

    SyndicationFeed result = feedRepository.GetSyndicationFeed();

    result.Items = opts.ApplyTo(result.Items.AsQuerable()).ToArray();

    return result;
}