OData V6.6.0不允许$ search

时间:2014-08-11 16:25:14

标签: search odata

我尝试使用OData V6.6.0 $搜索功能。我最初有5.2版本,我更新到6.6.0版本。但是,我仍然无法使用$ search。当我在url中使用它时

odata/Prescribers?$inlinecount=allpages&$top=20&$search=TEST';

我收到此错误消息'查询参数' $ search'不受支持。'

我是否需要执行其他操作才能添加$ search功能。顺便说一句,我也在我的控制器中使用EnableQuery。

    [EnableQuery(AllowedQueryOptions = System.Web.Http.OData.Query.AllowedQueryOptions.All)]

 public IQueryable<ContactList> Get()
        {
            return dbContext.ContactsList.AsQueryable();
        }

3 个答案:

答案 0 :(得分:1)

虽然这有点旧,但我想根据模型上的AllowSearchAttribute给你一个“$ search to $ filter”映射的实现。它是作为从EnableQueryAttribute派生的属性实现的。 “魔术”是获取查询的$search部分,将其转换为$filter子句,并在基础结构进一步处理之前将其从参数中删除。这是通过用更改的数组替换request.Properties[HttpPropertyKeys.RequestQueryNameValuePairsKey]来实现的。这是缓存,稍后处理将从中获取查询字段(请参阅request.GetQueryNameValuePairs)。

public class EnableQueryWithSearchAttribute : EnableQueryAttribute
{
    public Type ModelType { get; set; }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        var request = actionExecutedContext.Request;
        var query = request.GetQueryNameValuePairs().ToList();
        var searchParam = query.FirstOrDefault(q => q.Key == "$search");
        if (!String.IsNullOrWhiteSpace(searchParam.Key))
        {
            if (!String.IsNullOrWhiteSpace(searchParam.Value))
            {
                string filterString = null;
                var filter = query.FirstOrDefault(q => q.Key == "$filter");
                if (!String.IsNullOrWhiteSpace(filter.Key))
                {
                    filterString = filter.Value;
                }

                var odataSearchValue = searchParam.Value.Replace("'", "''");
                var props = this.ModelType
                    .GetProperties()
                    .Where(pi => pi.GetCustomAttribute<AllowSearchAttribute>() != null)
                    .Select(pi => pi.Name)
                    .ToList();

                if (props.Count > 0)
                {
                    if (!String.IsNullOrWhiteSpace(filterString))
                    {
                        filterString = "(" + filterString + ") and ";
                    }

                    filterString += "(contains(" +
                                    String.Join(", '" + odataSearchValue + "') or contains(", props) + ", '" +
                                    odataSearchValue + "'))";
                }

                request.Properties[HttpPropertyKeys.RequestQueryNameValuePairsKey] =
                    query.Where(q => q.Key != "$search" && q.Key != "$filter").Concat(new[] { new KeyValuePair<string, string>("$filter", filterString) }).ToArray();
            }
            else
            {
                request.Properties[HttpPropertyKeys.RequestQueryNameValuePairsKey] =
                    query.Where(q => q.Key != "$search").ToArray();
            }
        }

        base.OnActionExecuted(actionExecutedContext);
    }
}

AllowSearchAttribute是一个描述性属性,没有额外的信息。

[AttributeUsage(AttributeTargets.Property)]
public class AllowSearchAttribute : Attribute { }

在模型类上,您可以通过将[AllowSearch]属性应用于所需属性来指定应搜索哪些属性。在示例中,只会搜索TitleDescription

public class MyModel
{
    public int Id { get; set; }
    [AllowSearch]
    public string Title { get; set; }
    [AllowSearch]
    public string Description { get; set; }
    public string SomethingNotSearchable { get; set; }
}

在通常应用[EnableQuery]属性的方法中,您将使用派生的属性并指定模型类型:

[EnableQueryWithSearch(EnsureStableOrdering = true, ModelType = typeof(MyModel))]
[HttpGet]
public IQueryable<MyModel> Get()
{
    // your code here.
}

现在可以使用$ search参数调用OData端点,该参数将在内部映射到相应的$ filter参数。当前实现始终使用contains(...)操作,但您可以使用自定义[AllowSearch]参数轻松增强实现,这将发出其他操作。

希望这有助于某人。我无法在任何地方找到任何其他类型的实现,所以我想我会分享。

答案 1 :(得分:0)

WebApi目前不支持$ search。为了支持它,您可以从这里https://aspnetwebstack.codeplex.com/SourceControl/latest#OData/src/System.Web.OData/OData/Query/ODataQueryOptions.cs开始模拟其他查询选项,然后引用私有内置的dll。

答案 2 :(得分:0)

我明白了。如果在过滤器中使用substringof,则返回包含该字符串的值的记录。我使用$ filter和'或'运算符来检查多个列。

'&$filter=substringof(\'' + key + '\', NPI)' +
  'or substringof(\'' + key + '\', Zip)' +                        
  'or substringof(\'' + key + '\', PrescriberName)';

这显示了包含过滤器中字符串的所有记录。