【问题标题】:.NET Core 2.1 OData v4 modify $filter on server side.NET Core 2.1 OData v4 在服务器端修改 $filter
【发布时间】:2020-04-14 18:32:24
【问题描述】:

我需要在 .NET core 2.1 API 的服务器端修改$filter。我看过这些:

https://entityframework.net/knowledge-base/33660648/odata-v4-modify--filter-on-server-side

OData V4 modify $filter on server side

The best way to modify a WebAPI OData QueryOptions.Filter

(和其他几个)

他们都在做一些事情:

//Get the URL
var url = queryOptions.Request.RequestUri.AbsoluteUri;
//Then modify the URL
url = url.Replace("$filter=ID%20eq%201", "$filter=ID%20eq%202");
//Apply the URL
return queryOptions.ApplyTo(queryable);

问题是它出现在 .NET core 中没有RequestUri。我可以通过多种不同的方式获取查询:

var query = originalRequest.QueryString.Value;
//or a foreach loop
var filter = Request.Query;
foreach (var x in filter)
//...

但是QueryString.Value Request.Query 都给我一个错误“值没有设置器”

同样ApplyTo 方法不在 .NET Core 中。

在 .NET Core 中执行此操作的正确方法是什么?有没有我遗漏的包裹?

【问题讨论】:

    标签: c# .net-core odata


    【解决方案1】:

    @Xaphann 您可以通过以下方式扩展EnableQueryAttribute

    public class ExtendedEnableQueryAttribute : EnableQueryAttribute
    {
        public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
        {
            // ... second check in the if statement might be overkill - abundance of caution?
            if (queryOptions.Filter != null && queryOptions.Request.Query.ContainsKey("$filter"))
            {
                var stringValuesDict = new Dictionary<string, StringValues>();
    
                foreach(var kvPair in queryOptions.Request.Query.Where(d => !d.Key.Equals("$filter")))
                {
                    // This way the new StringValues instances are owned exclusively by substitute query collection
                    var values = new List<string>();
                    foreach(var value in kvPair.Value)
                    {
                        values.Add(value);
                    }
                    stringValuesDict.Add(kvPair.Key, new StringValues(values.ToArray()));
                }
                // Substitute the $filter option
                stringValuesDict.Add("$filter", new StringValues("ID eq 202"));
                // Substitute the request query collection
                queryOptions.Request.Query = new QueryCollection(stringValuesDict);
    
                queryOptions = new ODataQueryOptions(queryOptions.Context, queryOptions.Request);
            }
    
            return base.ApplyQuery(queryable, queryOptions);
        }
    }
    

    然后您可以继续将此扩展属性应用于您的控制器操作。 我对它进行了实际测试,它似乎适用于这样的表达式:

    ?$filter=ID eq 201&amp;$orderby=Name&amp;$select=Name

    如果这种方法适合你,我的建议是进行更广泛的测试,也许还写一些测试来验证行为

    【讨论】:

      猜你喜欢
      • 2016-02-13
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 2015-07-29
      • 2019-06-21
      • 1970-01-01
      相关资源
      最近更新 更多