修改的WebAPI的OData QueryOptions.Filter的最佳方式 [英] The best way to modify a WebAPI OData QueryOptions.Filter

查看:409
本文介绍了修改的WebAPI的OData QueryOptions.Filter的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用OData的示例项目在<一个href=\"http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations\">http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations.在得到我希望能够改变的EntitySetController的QueryOptions过滤器:

I am using the OData sample project at http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations. In the Get I want to be able to change the Filter in the QueryOptions of the EntitySetController:

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 作为它是只读的。然而,我可以从修改 RawValue 创建 FilterQueryOption 的另一个实例,但我不能把它分配给 this.QueryOptions.Filter ,因为这是只读了。

I would like to be able to find properties that are specifically referred to. I can do this by parsing this.QueryOptions.Filter.RawValue for the property names but I cannot update the RawValue as it is read only. I can however create another instance of FilterQueryOption from the modified RawValue but I cannot assign it to this.QueryOptions.Filter as this is read only too.

我想我可以调用新的过滤器的 ApplyTo 传递给它 _context.Products ,但随后我将需要分别致电 ApplyTo QueryOptions 的其他属性的像跳过排序依据。有没有更好的解决方案比这个?

I guess I could call the new filter's ApplyTo passing it _context.Products, but then I will need to separately call the ApplyTo of the other properties of QueryOptions like Skip and OrderBy. Is there a better solution than this?

更新

我试过如下:

    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 名单,但在方法返回时我没有得到任何项目。我试图把 [可查询(AllowedQueryOptions = AllowedQueryOptions.All)] 重新打开,但没有任何效果。任何想法,为什么我没有得到一个项目?

and it seems to be working up to a point. If I set a breakpoint I can see my products in the unencryptedProducts list, but when the method returns I don't get any items. I tried putting the [Queryable(AllowedQueryOptions=AllowedQueryOptions.All)] back on again but it had no effect. Any ideas why I am not getting an items?

更新2

我发现我的查询已被应用了两次,即使我不使用可查询属性。这意味着,即使我有项目返回清单被查询用未加密的价值,因此返回没有值。

I discovered that my query was being applied twice even though I am not using the Queryable attribute. This meant that even though I had items to return the List was being queried with the unencrypted value and therefore no values were being returned.

我试图使用 ODataController 而不是:

public class ODriversController : ODataController
{

    //[Authorize()]
    //[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    public IQueryable<Products> Get(ODataQueryOptions options)
    {

和这个工作!这是否表明,在 EntitySetController

and this worked! Does this indicate that there is a bug in EntitySetController?

推荐答案

您可能会需要重新ODataQueryOptions解决您的​​问题。如果我们要修改添加$排序依据,你可以做到这一点像我们说:

You would probably need to regenerate ODataQueryOptions to solve your issue. Let's say if you want to modify to add $orderby, you can do this like:

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);

这篇关于修改的WebAPI的OData QueryOptions.Filter的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆