首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ASP .NET MVC 4 WebApi:手动处理OData查询

ASP .NET MVC 4 WebApi:手动处理OData查询
EN

Stack Overflow用户
提问于 2012-05-28 16:07:17
回答 4查看 23.2K关注 0票数 56

我有一个使用ASPMVC4提供的 WebAPI 创建的Web服务。我知道WebAPI工作在其上的层会自动处理OData查询(如$filter$top$skip),但如果我想自己处理过滤怎么办?

I don't simply return data from my database,但我有另一个层,它添加了一些属性,进行了一些转换等。所以查询我的所有数据,转换它们,并将它们返回到WebAPI类以进行OData过滤还不够好。当然,它非常慢,而且通常是一个糟糕的想法。

那么,有没有一种方法可以将OData查询参数从WebAPI入口点传播到我调用以获取和转换数据的函数?

例如,GET to /api/people?$skip=10&$top=10将在服务器上调用:

代码语言:javascript
运行
复制
public IQueryable<Person> get() {
    return PersonService.get(SomethingAboutCurrentRequest.CurrentOData);
}

PersonService

代码语言:javascript
运行
复制
public IQueryable<Person> getPeople(var ODataQueries) {
    IQueryable<ServerSidePerson> serverPeople = from p in dbContext.ServerSidePerson select p;
    // Make the OData queries
    // Skip
    serverPeople = serverPeople.Skip(ODataQueries.Skip);
    // Take
    serverPeople = serverPeople.Take(ODataQueries.Take);
    // And so on
    // ...

    // Then, convert them
    IQueryable<Person> people = Converter.convertPersonList(serverPeople);
    return people;
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-03-19 17:35:56

我只是偶然发现了这篇旧文章,我添加了这个答案,因为现在自己处理OData查询非常容易。下面是一个例子:

代码语言:javascript
运行
复制
[HttpGet]
[ActionName("Example")]
public IEnumerable<Poco> GetExample(ODataQueryOptions<Poco> queryOptions)
{
    var data = new Poco[] { 
        new Poco() { id = 1, name = "one", type = "a" },
        new Poco() { id = 2, name = "two", type = "b" },
        new Poco() { id = 3, name = "three", type = "c" }
    };

    var t = new ODataValidationSettings() { MaxTop = 2 };
    queryOptions.Validate(t);

    //this is the method to filter using the OData framework
    //var s = new ODataQuerySettings() { PageSize = 1 };
    //var results = queryOptions.ApplyTo(data.AsQueryable(), s) as IEnumerable<Poco>;

    //or DIY
    var results = data;
    if (queryOptions.Skip != null) 
        results = results.Skip(queryOptions.Skip.Value);
    if (queryOptions.Top != null)
        results = results.Take(queryOptions.Top.Value);

    return results;
}

public class Poco
{
    public int id { get; set; }
    public string name { get; set; }
    public string type { get; set; }
}
票数 42
EN

Stack Overflow用户

发布于 2012-05-28 17:12:21

来自URL的查询被翻译成一个LINQ表达式树,然后根据您的操作返回的IQueryable执行。您可以分析表达式并以任何您想要的方式提供结果。缺点是您需要实现IQueryable,这并不是非常容易。如果你感兴趣,可以看看这篇博文系列:http://blogs.msdn.com/b/vitek/archive/2010/02/25/data-services-expressions-part-1-intro.aspx。它谈到了WCF数据服务,但Web API使用的筛选器表达式将非常相似。

票数 4
EN

Stack Overflow用户

发布于 2012-05-28 18:07:31

使用Web-api的一种方法是使用客户消息处理程序http://www.asp.net/web-api/overview/working-with-http/http-message-handlers

编写一个自定义处理程序,如下所示:

代码语言:javascript
运行
复制
public class CustomHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken).ContinueWith(
                (task) =>
                {
                    HttpResponseMessage response = task.Result;
                    var persons = response.Content.ReadAsAsync<IQueryable<Person>>().Result;
                    var persons2 = new List<Person>(); //This can be the modified model completely different
                    foreach (var item in persons)
                    {
                        item.Name = "changed"; // here you can change the data
                        //persons2.Add(....); //Depending on the results modify this custom model
                    }
                    //overwrite the response
                    response = new HttpResponseMessage<IEnumerable<Person>>(persons2); 
                    return response;
                }
            );
        }
    }

global.asax.cs中的注册

应用程序类中的方法:

代码语言:javascript
运行
复制
static void Configure(HttpConfiguration config)
 {
     config.MessageHandlers.Add(new CustomHandler()); 
 }

protected void Application_Start()
{
     ....
     .....
     //call the configure method
     Configure(GlobalConfiguration.Configuration);
 }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10781309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档