修改的WebAPI的OData QueryOptions.Filter的最佳方式 [英] The best way to modify a 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屋!