简体   繁体   English

通过Web API中的属性限制OData $ filter

[英]Limit OData $filter by property in Web API

I want to only allow some properties to be used in OData query $filter option. 我只想在OData查询$filter选项中使用某些属性。

I see that there an AllowedOrderByProperties parameter to EnableQueryAttribute , but I didn't find another for $filter. 我看到有一个AllowedOrderByProperties参数EnableQueryAttribute ,但我没有找到另一种为$过滤器。 Did I just miss it? 我只是想念它吗? If not, what would it take to implement it? 如果没有,实施该计划将需要什么?

You can try the following: 您可以尝试以下方法:

once you have the builder, you can list the properties of the entitySet then you can mention if the field is filterable or not. 一旦有了构建器,就可以列出entitySet的属性,然后可以提及该字段是否可过滤。

var entityTypeConfig = builder.EntitySet<SomeType>("SomeType").EntityType;
entityTypeConfig.Property(x => x.SomeField);
entityTypeConfig.Property(x => x.SomeField2).IsNotFilterable().IsNonFilterable();
// not sure what is the difference between them

and in the controller action (the httpGet for example) add 并在控制器操作(例如httpGet)中添加

options.Filter.Validate(allowedOptions);

in case a field is not filterable this would throw an exception. 如果字段不可过滤,则将引发异常。

I think you are going to be rolling your own filter validation since there isn't any built-in language around what you are filtering. 我认为您将要进行自己的过滤器验证,因为围绕您所过滤的内容没有任何内置语言。 This may or may not be helpful for you but I would recommend using a ModelBinder to perform your validation so when your controller methods are run, you've already validated the content of all parameters. 这可能对您有帮助,也可能没有帮助,但我建议您使用ModelBinder进行验证,因此在运行控制器方法时,您已经验证了所有参数的内容。 My suggestion would be to return an object from your ModelBinder that meets whatever your business needs are in your app. 我的建议是从ModelBinder返回一个对象,该对象可以满足您应用程序中的业务需求。 You can certainly use the OData constructs to help you do that. 您当然可以使用OData构造来帮助您做到这一点。 Here's a snippet of code from our system that starts this process. 这是我们系统中启动该过程的代码段。 It may be helpful to get you going on your own Binder. 使您自己使用活页夹可能会有所帮助。

private T CreateQueryOptions<T>(string url, [CallerMemberName] string caller = null) where T : class
{
    var httpRequest = new HttpRequestMessage(HttpMethod.Get, url);
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.EntitySet<T>(caller);
    var odata =  new ODataQueryOptions<T>(new ODataQueryContext(modelBuilder.GetEdmModel(), typeof(T)), httpRequest);
    // rest of your code here to validate OData parameters  Generics may not be appropriate for you.
}

But this works for me in a real system with 100's of millions of calls / day. 但这在每天有100亿次呼叫的真实系统中works for me有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM