From a2d5113c5ce2632458b047a7ad1b8c791162ecc9 Mon Sep 17 00:00:00 2001 From: Barry GIBNEY Date: Thu, 21 Nov 2024 13:09:24 +0000 Subject: [PATCH] Stop HttpRequestMessage causing 'request message was already sent' error. Also updated to use Array.Empty() as an improvement --- .../AzureMaps/AzureMapsService.cs | 100 ++++++++++-------- 1 file changed, 54 insertions(+), 46 deletions(-) diff --git a/Web/Edubase.Services/IntegrationEndPoints/AzureMaps/AzureMapsService.cs b/Web/Edubase.Services/IntegrationEndPoints/AzureMaps/AzureMapsService.cs index 32a0ac15a..a414afaef 100644 --- a/Web/Edubase.Services/IntegrationEndPoints/AzureMaps/AzureMapsService.cs +++ b/Web/Edubase.Services/IntegrationEndPoints/AzureMaps/AzureMapsService.cs @@ -33,71 +33,79 @@ public AzureMapsService(HttpClient httpClient) _azureMapsClient = httpClient; } - public async Task SearchAsync(string text, bool isTypeahead, CancellationToken cancellationToken = default) + public async Task SearchAsync(string text, bool isTypeahead, + CancellationToken cancellationToken = default) { text = text.Clean(); if (string.IsNullOrWhiteSpace(text)) { - return new PlaceDto[0]; + return Array.Empty(); } - var request = new HttpRequestMessage( - HttpMethod.Get, - $"/search/address/json?api-version=1.0&countrySet=GB&typeahead={(isTypeahead ? "true" : "false")}&limit=10&query={text}&subscription-key={_apiKey}"); - - using (var response = await RetryPolicy.ExecuteAsync(async () => await _azureMapsClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken))) + var response = await RetryPolicy.ExecuteAsync(async () => { - var stream = await response.Content.ReadAsStreamAsync(); - - if (!response.IsSuccessStatusCode) + using (var request = new HttpRequestMessage( + HttpMethod.Get, + $"/search/address/json?api-version=1.0&countrySet=GB&typeahead={(isTypeahead ? "true" : "false")}&limit=10&query={text}&subscription-key={_apiKey}")) { - return new PlaceDto[0]; + return await _azureMapsClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, + cancellationToken); } + }); + + if (!response.IsSuccessStatusCode) + { + return Array.Empty(); + } - using (var sr = new StreamReader(stream)) - using (JsonReader reader = new JsonTextReader(sr)) + using (var stream = await response.Content.ReadAsStreamAsync()) + using (var sr = new StreamReader(stream)) + using (JsonReader reader = new JsonTextReader(sr)) + { + var serializer = new JsonSerializer(); + var azureMapsResponse = serializer.Deserialize(reader); + var results = azureMapsResponse.results + .Where(result => result.type != "Cross Street" + && !(result.entityType != null && + result.entityType == "CountrySecondarySubdivision")) + .ToList(); + + var municipalities = results.Where(x => x.entityType == "Municipality").ToList(); + var subMunicipalities = results.Where(x => x.entityType == "MunicipalitySubdivision").ToList(); + // If the response contains a "MunicipalitySubdivision" with the same name as a returned Municipality (town), + // use the coordinates of that result for the position of the town and remove it from the result set. + // This addresses an issue where a small number of towns have inaccurate coordinates associated with them. + foreach (var municipality in municipalities) { - var serializer = new JsonSerializer(); - var azureMapsResponse = serializer.Deserialize(reader); - var results = azureMapsResponse.results - .Where(result => result.type != "Cross Street" - && !(result.entityType != null && result.entityType == "CountrySecondarySubdivision")) - .ToList(); - - var municipalities = results.Where(x => x.entityType == "Municipality").ToList(); - var subMunicipalities = results.Where(x => x.entityType == "MunicipalitySubdivision").ToList(); - // If the response contains a "MunicipalitySubdivision" with the same name as a returned Municipality (town), - // use the coordinates of that result for the position of the town and remove it from the result set. - // This addresses an issue where a small number of towns have inaccurate coordinates associated with them. - foreach (var municipality in municipalities) + var child = subMunicipalities.FirstOrDefault( + x => x.address.municipality == municipality.address.municipality + && x.address.municipalitySubdivision == municipality.address.municipality); + if (child == null) { - var child = subMunicipalities.FirstOrDefault( - x => x.address.municipality == municipality.address.municipality - && x.address.municipalitySubdivision == municipality.address.municipality); - if (child == null) - { - continue; - } - municipality.position.lat = child.position.lat; - municipality.position.lon = child.position.lon; - results.Remove(child); + continue; } - var parsedResults = results.Select(x => new PlaceDto(GetAddressDescription(x, text), new LatLon(x.position.lat, x.position.lon))).ToArray(); + municipality.position.lat = child.position.lat; + municipality.position.lon = child.position.lon; + results.Remove(child); + } + + var parsedResults = results.Select(x => + new PlaceDto(GetAddressDescription(x, text), new LatLon(x.position.lat, x.position.lon))).ToArray(); - // If the search string is a postcode and none of the returned results contain the given post code, then return zero results, so that the search is deferred to OS places. - if (text.IsUkPostCode()) + // If the search string is a postcode and none of the returned results contain the given post code, then return zero results, so that the search is deferred to OS places. + if (text.IsUkPostCode()) + { + var postCode = text.Remove(" ").ToLower(); + if (!parsedResults.Any(x => + (x.Name ?? "").ToLower().Remove(" ").Contains("," + postCode.Remove(" ")))) { - var postCode = text.Remove(" ").ToLower(); - if (!parsedResults.Any(x => (x.Name ?? "").ToLower().Remove(" ").Contains("," + postCode.Remove(" ")))) - { - return new PlaceDto[0]; - } + return new PlaceDto[0]; } - - return parsedResults; } + + return parsedResults; } }