我尝试使用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();
}
答案 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]
属性应用于所需属性来指定应搜索哪些属性。在示例中,只会搜索Title
和Description
:
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)';
这显示了包含过滤器中字符串的所有记录。