I have a restful webapi, and I want to support a queryparameter for searching something like ?q=
What I thought about doing is using delegatingHandler for changing the response Basically creating a QueryHandler for each type of Resource
BaseQueryHandler method would look like so
HttpResponseMessage IQueryHandler.Query(HttpResponseMessage response, string query)
{
httpResponse = response;
T content;
if (response.TryGetContentValue(out content))
{
response = Request.CreateResponse(Query(content, query));
}
return response;
}
Concrete QueryHandler like so
public override Organization Query(Organization content, string query)
{
query = query.ToLower();
var organization = content.ChildOrganizations?.Where(o => o.Name.ToLower().Contains(query));
return
}
UPDATE:
I will definitely have a look at OData.
What I've done so far is to implement my QueryHandler and then use an extension method for searching objects for fields and values
public static IEnumerable<T> LikeOr<T>(this IEnumerable<T> source, string columnName, string searchTerm)
{
IEnumerable<string> words =
searchTerm.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).Where(x => x.Length > 1);
var sb = new StringBuilder();
for (int i = 0; i < words.Count(); i++)
{
if (i != 0)
sb.Append(" || ");
sb.Append(words.First().IsNumeric() ? $"{columnName} = @{i}" : $"{columnName}.Contains(@{i})");
}
var intSearch = 0;
if (int.TryParse(words.First(), out intSearch))
return source.Where(sb.ToString(), intSearch);
return source.Where(sb.ToString(), words.ToArray());
}
and then using that in my concrete searcHandler implementation like so
public override IEnumerable<Organization> Search(IEnumerable<Organization> content, string query)
{
var searchTerm = query.Split(':');
var field = searchTerm[0];
var term = searchTerm[1];
var entitites = content.LikeOr(field, term);
return entitites;
}
(actually found this in another answer regard dynamic.Linq (dont remember the URL, will update when i refind it, to give proper credit)
Does any of you have a better way of doing this?
Normally you would properly have the query parameter on all actions, I'd like to NOT have that :)