Skip to content

Commit 2864a47

Browse files
committed
fix: Update BingTextSearch to return strongly-typed KernelSearchResults<BingWebPage> per PR #13318
- Change ITextSearch<BingWebPage>.GetSearchResultsAsync to return KernelSearchResults<BingWebPage> instead of <object> - Add strongly-typed helper GetResultsAsBingWebPageAsync returning IAsyncEnumerable<BingWebPage> - Update tests to expect strongly-typed results (no manual casting needed) - Fix duplicate XML comment issue This aligns with PR #13318 interface type safety improvements and eliminates wasteful casting.
1 parent 1749345 commit 2864a47

2 files changed

Lines changed: 35 additions & 10 deletions

File tree

dotnet/src/Plugins/Plugins.UnitTests/Web/Bing/BingTextSearchTests.cs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public async Task GenericGetSearchResultsAsyncWithSnippetContainsFilterProducesC
372372
Skip = 0,
373373
Filter = page => page.Snippet!.Contains("semantic")
374374
};
375-
KernelSearchResults<object> result = await textSearch.GetSearchResultsAsync("What is the Semantic Kernel?", searchOptions);
375+
KernelSearchResults<BingWebPage> result = await textSearch.GetSearchResultsAsync("What is the Semantic Kernel?", searchOptions);
376376

377377
// Assert - Verify LINQ Snippet.Contains() converted to Bing's inbody: operator
378378
var requestUris = this._messageHandlerStub.RequestUris;
@@ -852,19 +852,17 @@ public async Task GenericGetSearchResultsAsyncFilterTranslationPreservesBingWebP
852852
Skip = 0,
853853
Filter = page => page.Language == "en" && page.DisplayUrl!.Contains("microsoft")
854854
};
855-
KernelSearchResults<object> result = await textSearch.GetSearchResultsAsync("technology", searchOptions);
855+
KernelSearchResults<BingWebPage> result = await textSearch.GetSearchResultsAsync("technology", searchOptions);
856856

857857
// Assert - Verify BingWebPage objects have all expected properties
858858
Assert.NotNull(result);
859859
Assert.NotNull(result.Results);
860860
var resultList = await result.Results.ToListAsync();
861861
Assert.Equal(10, resultList.Count);
862-
foreach (var obj in resultList)
862+
foreach (var page in resultList)
863863
{
864-
Assert.NotNull(obj);
865-
Assert.IsType<BingWebPage>(obj);
866-
var page = (BingWebPage)obj;
867-
// Verify key properties are populated
864+
Assert.NotNull(page);
865+
// Verify key properties are populated - now strongly typed, no cast needed!
868866
Assert.NotNull(page.Name);
869867
Assert.NotNull(page.Url);
870868
Assert.NotNull(page.Snippet);

dotnet/src/Plugins/Plugins.Web/Bing/BingTextSearch.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,18 @@ Task<KernelSearchResults<TextSearchResult>> ITextSearch<BingWebPage>.GetTextSear
9494
}
9595

9696
/// <inheritdoc/>
97-
Task<KernelSearchResults<object>> ITextSearch<BingWebPage>.GetSearchResultsAsync(string query, TextSearchOptions<BingWebPage>? searchOptions, CancellationToken cancellationToken)
97+
async Task<KernelSearchResults<BingWebPage>> ITextSearch<BingWebPage>.GetSearchResultsAsync(string query, TextSearchOptions<BingWebPage>? searchOptions, CancellationToken cancellationToken)
9898
{
9999
var legacyOptions = searchOptions != null ? ConvertToLegacyOptions(searchOptions) : new TextSearchOptions();
100-
return this.GetSearchResultsAsync(query, legacyOptions, cancellationToken);
100+
101+
BingSearchResponse<BingWebPage>? searchResponse = await this.ExecuteSearchAsync(query, legacyOptions, cancellationToken).ConfigureAwait(false);
102+
103+
long? totalCount = legacyOptions.IncludeTotalCount ? searchResponse?.WebPages?.TotalEstimatedMatches : null;
104+
105+
return new KernelSearchResults<BingWebPage>(
106+
this.GetResultsAsBingWebPageAsync(searchResponse, cancellationToken),
107+
totalCount,
108+
GetResultsMetadata(searchResponse));
101109
}
102110

103111
#region private
@@ -452,7 +460,7 @@ private async Task<HttpResponseMessage> SendGetRequestAsync(string query, TextSe
452460
}
453461

454462
/// <summary>
455-
/// Return the search results as instances of <see cref="BingWebPage"/>.
463+
/// Return the search results as instances of <see cref="object"/>.
456464
/// </summary>
457465
/// <param name="searchResponse">Response containing the web pages matching the query.</param>
458466
/// <param name="cancellationToken">Cancellation token</param>
@@ -470,6 +478,25 @@ private async IAsyncEnumerable<object> GetResultsAsWebPageAsync(BingSearchRespon
470478
}
471479
}
472480

481+
/// <summary>
482+
/// Return the search results as strongly-typed <see cref="BingWebPage"/> instances.
483+
/// </summary>
484+
/// <param name="searchResponse">Response containing the web pages matching the query.</param>
485+
/// <param name="cancellationToken">Cancellation token</param>
486+
private async IAsyncEnumerable<BingWebPage> GetResultsAsBingWebPageAsync(BingSearchResponse<BingWebPage>? searchResponse, [EnumeratorCancellation] CancellationToken cancellationToken)
487+
{
488+
if (searchResponse is null || searchResponse.WebPages is null || searchResponse.WebPages.Value is null)
489+
{
490+
yield break;
491+
}
492+
493+
foreach (var webPage in searchResponse.WebPages.Value)
494+
{
495+
yield return webPage;
496+
await Task.Yield();
497+
}
498+
}
499+
473500
/// <summary>
474501
/// Return the search results as instances of <see cref="TextSearchResult"/>.
475502
/// </summary>

0 commit comments

Comments
 (0)