修改Web API OData查询Options.Filter的最佳方法

时间:2013-05-08 12:25:40

标签: asp.net-web-api odata

我在http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations使用OData示例项目。在Get我希望能够在EntitySetController的QueryOptions中更改Filter:

public class ProductsController : EntitySetController<Product, int>
{
    ProductsContext _context = new ProductsContext();

    [Queryable(AllowedQueryOptions=AllowedQueryOptions.All)]
    public override IQueryable<Product> Get()
    {
        var products = QueryOptions.ApplyTo(_context.Products).Cast<Product>();
        return products.AsQueryable();
    }

我希望能够找到专门提到的属性。我可以通过解析this.QueryOptions.Filter.RawValue获取属性名称来执行此操作,但我无法更新RawValue,因为它是只读的。但是,我可以从修改后的FilterQueryOption创建另一个RawValue实例,但我无法将其分配给this.QueryOptions.Filter,因为它也是只读的。

我想我可以调用新过滤器ApplyTo传递_context.Products,但我需要单独调用ApplyTo的其他属性的QueryOptions,如{ {1}}和Skip。有比这更好的解决方案吗?

更新

我尝试了以下内容:

OrderBy

它似乎正在努力。如果我设置断点,我可以在 public override IQueryable<Product> Get() { IQueryable<Product> encryptedProducts = _context.Products; var filter = QueryOptions.Filter; if (filter != null && filter.RawValue.Contains("Name")) { var settings = new ODataQuerySettings(); var originalFilter = filter.RawValue; var newFilter = ParseAndEncyptValue(originalFilter); filter = new FilterQueryOption(newFilter, QueryOptions.Context); encryptedProducts = filter.ApplyTo(encryptedProducts, settings).Cast<Product>(); if (QueryOptions.OrderBy != null) { QueryOptions.OrderBy.ApplyTo<Product>(encryptedProducts); } } else { encryptedProducts = QueryOptions.ApplyTo(encryptedProducts).Cast<Product>(); } var unencryptedProducts = encryptedProducts.Decrypt().ToList(); return unencryptedProducts.AsQueryable(); } 列表中看到我的产品,但是当方法返回时,我没有得到任何项目。我尝试重新启用unencryptedProducts但它没有效果。任何想法,为什么我没有得到物品?

更新2

我发现即使我没有使用[Queryable(AllowedQueryOptions=AllowedQueryOptions.All)]属性,我的查询也会被应用两次。这意味着即使我有要返回的项目,也会使用未加密的值查询List,因此没有返回任何值。

我尝试使用Queryable代替:

ODataController

这很有效!这是否表示public class ODriversController : ODataController { //[Authorize()] //[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)] public IQueryable<Products> Get(ODataQueryOptions options) { 中存在错误?

1 个答案:

答案 0 :(得分:4)

您可能需要重新生成ODataQueryOptions才能解决您的问题。假设您想要修改以添加$ orderby,您可以这样做:

string url = HttpContext.Current.Request.Url.AbsoluteUri;
url += "&$orderby=name";
var request = new HttpRequestMessage(HttpMethod.Get, url);
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Product");
var options = new ODataQueryOptions<Product>(new ODataQueryContext(modelBuilder.GetEdmModel(), typeof(Product)), request);