odata.net icon indicating copy to clipboard operation
odata.net copied to clipboard

Support $search in OData Client library

Open sliekens opened this issue 1 year ago • 7 comments

Hello,

I want to use $search with the OData client library, but it's not implemented: the RequireLegalCustomQueryOption method throws NotSupportedException

The exception is thrown here:

https://github.com/OData/odata.net/blob/5d8eafe3cc16777bcf7d3f648467d8042143217c/src/Microsoft.OData.Client/ALinq/ResourceBinder.cs#L2833-L2899

Search should be added to this switch.

Assemblies affected

Microsoft.OData.Client 7.18.0

Reproduce steps

var dsc = new DataServiceContext();
dsc.CreateQuery<object>("items").AddQueryOption("$search", "odata").ToList();

Expected result

URI is created with $search=odata

Actual result

Exception thrown: 'System.NotSupportedException' in Microsoft.OData.Client.dll: 'The query option '$search' is not supported or is controlled by the OData service.'
   at Microsoft.OData.Client.ResourceBinder.ValidationRules.RequireLegalCustomQueryOption(Expression e, ResourceExpression target)
   at Microsoft.OData.Client.ResourceBinder.AnalyzeAddCustomQueryOption(MethodCallExpression mce)
   at Microsoft.OData.Client.ResourceBinder.VisitMethodCall(MethodCallExpression mce)
   at Microsoft.OData.Client.ALinqExpressionVisitor.Visit(Expression exp)
   at Microsoft.OData.Client.ResourceBinder.Bind(Expression e, DataServiceContext context)
   at Microsoft.OData.Client.DataServiceQueryProvider.Translate(Expression e)
   at Microsoft.OData.Client.DataServiceQuery`1.Execute()
   at Microsoft.OData.Client.DataServiceQuery`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

Additional detail

The switch in RequireLegalCustomQueryOption needs to be expanded with $search support.

sliekens avatar Nov 23 '23 15:11 sliekens

Same issue as #2736

sliekens avatar Nov 23 '23 16:11 sliekens

Thank you @sliekens for reporting the feature gap. We'll triage it and add it to add it to our backlog. If you're in a position to contribute a pull request we'd be happy to review.

gathogojr avatar Nov 28 '23 16:11 gathogojr

May I workaround it somehow?

stanb avatar Mar 04 '24 09:03 stanb

May I workaround it somehow?

Try 'search' without the dollar sign, if your backend supports it.

sliekens avatar Mar 04 '24 10:03 sliekens

May I workaround it somehow?

Try 'search' without the dollar sign, if your backend supports it.

My backend supports odata $search option

stanb avatar Mar 04 '24 12:03 stanb

@stanb is the dollar sign required? The NotSupportedException is only thrown for "$search", but "search" works fine.

sliekens avatar Mar 04 '24 12:03 sliekens

@sliekens I found workaround

        EventHandler<BuildingRequestEventArgs> buildingRequestHandler = (object? sender, BuildingRequestEventArgs e) =>
        {
            if (searchTerm is not null)
            {
                var searchOption = $"$search={searchTerm}";
                var uriBuilder = new UriBuilder(e.RequestUri);
                uriBuilder.Query = uriBuilder.Query == string.Empty ? searchOption : string.Join("&", uriBuilder.Query, searchOption);
                e.RequestUri = uriBuilder.Uri;
            }
        };

        _client.BuildingRequest += buildingRequestHandler;

        var response = await query.ExecuteAsync();

        _client.BuildingRequest -= buildingRequestHandler;

stanb avatar Mar 04 '24 13:03 stanb