我有一个使用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
将在服务器上调用:
public IQueryable<Person> get() {
return PersonService.get(SomethingAboutCurrentRequest.CurrentOData);
}
在PersonService
中
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;
}
发布于 2013-03-19 17:35:56
我只是偶然发现了这篇旧文章,我添加了这个答案,因为现在自己处理OData查询非常容易。下面是一个例子:
[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; }
}
发布于 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使用的筛选器表达式将非常相似。
发布于 2012-05-28 18:07:31
使用Web-api的一种方法是使用客户消息处理程序http://www.asp.net/web-api/overview/working-with-http/http-message-handlers
编写一个自定义处理程序,如下所示:
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中的注册
应用程序类中的方法:
static void Configure(HttpConfiguration config)
{
config.MessageHandlers.Add(new CustomHandler());
}
protected void Application_Start()
{
....
.....
//call the configure method
Configure(GlobalConfiguration.Configuration);
}
https://stackoverflow.com/questions/10781309
复制相似问题