From 6212c4b78e306ff943730469dfe92b18d26d1db3 Mon Sep 17 00:00:00 2001
From: JustinCanton <67930245+JustinCanton@users.noreply.github.com>
Date: Thu, 18 Aug 2022 19:07:23 -0400
Subject: [PATCH 1/4] fix(mapbox-geocoding): fixing an issue where the query is
 not properly encoded

---
 src/Geo.MapBox/Services/MapBoxGeocoding.cs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/Geo.MapBox/Services/MapBoxGeocoding.cs b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
index f073f85..4bd4925 100644
--- a/src/Geo.MapBox/Services/MapBoxGeocoding.cs
+++ b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
@@ -126,6 +126,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
 
             var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, GeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, parameters.Query));
             var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, GeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, HttpUtility.UrlEncode(parameters.Query)));
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
             query.Add("autocomplete", parameters.ReturnAutocomplete.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());

From 6b8469e5015e97ef8373b7134ce5adbe0128eb2e Mon Sep 17 00:00:00 2001
From: JustinCanton <67930245+JustinCanton@users.noreply.github.com>
Date: Thu, 18 Aug 2022 19:08:00 -0400
Subject: [PATCH 2/4] feat: updating how query strings are created to be more
 inline with standards

---
 src/Geo.ArcGIS/Services/ArcGISGeocoding.cs    | 103 ++++++------
 src/Geo.Bing/Services/BingGeocoding.cs        |  49 +++---
 src/Geo.Google/Services/GoogleGeocoding.cs    | 151 +++++++++---------
 src/Geo.Here/Services/HereGeocoding.cs        | 101 ++++++------
 src/Geo.MapBox/Services/MapBoxGeocoding.cs    |  45 +++---
 .../Services/MapQuestGeocoding.cs             |  47 +++---
 src/Source.props                              |   9 ++
 .../Services/ArcGISGeocodingShould.cs         |  32 ++--
 .../Services/BingGeocodingShould.cs           |  34 ++--
 .../Services/GoogleGeocodingShould.cs         | 106 ++++++------
 .../Services/HereGeocodingShould.cs           | 140 +++++++++-------
 .../Services/MapBoxGeocodingShould.cs         |  30 ++--
 .../Services/MapQuestGeocodingShould.cs       |  22 +--
 13 files changed, 464 insertions(+), 405 deletions(-)

diff --git a/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs b/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs
index 750dc25..980862f 100644
--- a/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs
+++ b/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs
@@ -7,14 +7,12 @@ namespace Geo.ArcGIS.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Configuration;
     using System.Globalization;
     using System.Linq;
     using System.Net.Http;
     using System.Threading;
     using System.Threading.Tasks;
-    using System.Web;
     using Geo.ArcGIS.Abstractions;
     using Geo.ArcGIS.Enums;
     using Geo.ArcGIS.Models.Exceptions;
@@ -22,6 +20,7 @@ namespace Geo.ArcGIS.Services
     using Geo.ArcGIS.Models.Responses;
     using Geo.Core;
     using Geo.Core.Extensions;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging;
     using Microsoft.Extensions.Logging.Abstractions;
@@ -161,15 +160,15 @@ internal async Task<Uri> BuildAddressCandidateRequest(AddressCandidateParameters
             }
 
             var uriBuilder = new UriBuilder(CandidatesUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
-            query.Add("f", "json");
-            query.Add("outFields", "Match_addr,Addr_type");
+            var query = QueryString.Empty;
+            query = query.Add("f", "json");
+            query = query.Add("outFields", "Match_addr,Addr_type");
 
-            query.Add("singleLine", parameters.SingleLineAddress);
+            query = query.Add("singleLine", parameters.SingleLineAddress);
 
-            AddStorageParameter(parameters, query);
+            AddStorageParameter(parameters, ref query);
 
-            await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
+            query = await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
 
             uriBuilder.Query = query.ToString();
 
@@ -185,13 +184,13 @@ internal async Task<Uri> BuildAddressCandidateRequest(AddressCandidateParameters
         internal async Task<Uri> BuildPlaceCandidateRequest(PlaceCandidateParameters parameters, CancellationToken cancellationToken)
         {
             var uriBuilder = new UriBuilder(CandidatesUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
-            query.Add("f", "json");
-            query.Add("outFields", "Place_addr,PlaceName");
+            var query = QueryString.Empty;
+            query = query.Add("f", "json");
+            query = query.Add("outFields", "Place_addr,PlaceName");
 
             if (!string.IsNullOrWhiteSpace(parameters.Category))
             {
-                query.Add("category", parameters.Category);
+                query = query.Add("category", parameters.Category);
             }
             else
             {
@@ -200,7 +199,7 @@ internal async Task<Uri> BuildPlaceCandidateRequest(PlaceCandidateParameters par
 
             if (parameters.Location != null)
             {
-                query.Add("location", parameters.Location.ToString());
+                query = query.Add("location", parameters.Location.ToString());
             }
             else
             {
@@ -209,16 +208,16 @@ internal async Task<Uri> BuildPlaceCandidateRequest(PlaceCandidateParameters par
 
             if (parameters.MaximumLocations > 0 && parameters.MaximumLocations <= 50)
             {
-                query.Add("maxLocations", parameters.MaximumLocations.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("maxLocations", parameters.MaximumLocations.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
                 _logger.ArcGISWarning(_localizer["Invalid Maximum Locations"]);
             }
 
-            AddStorageParameter(parameters, query);
+            AddStorageParameter(parameters, ref query);
 
-            await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
+            query = await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
 
             uriBuilder.Query = query.ToString();
 
@@ -234,8 +233,8 @@ internal async Task<Uri> BuildPlaceCandidateRequest(PlaceCandidateParameters par
         internal Task<Uri> BuildSuggestRequest(SuggestParameters parameters, CancellationToken cancellationToken)
         {
             var uriBuilder = new UriBuilder(SuggestUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
-            query.Add("f", "json");
+            var query = QueryString.Empty;
+            query = query.Add("f", "json");
 
             if (string.IsNullOrWhiteSpace(parameters.Text))
             {
@@ -244,11 +243,11 @@ internal Task<Uri> BuildSuggestRequest(SuggestParameters parameters, Cancellatio
                 throw new ArgumentException(error, nameof(parameters.Text));
             }
 
-            query.Add("text", parameters.Text);
+            query = query.Add("text", parameters.Text);
 
             if (parameters.Location != null)
             {
-                query.Add("location", parameters.Location.ToString());
+                query = query.Add("location", parameters.Location.ToString());
             }
             else
             {
@@ -257,7 +256,7 @@ internal Task<Uri> BuildSuggestRequest(SuggestParameters parameters, Cancellatio
 
             if (!string.IsNullOrWhiteSpace(parameters.Category))
             {
-                query.Add("category", parameters.Category);
+                query = query.Add("category", parameters.Category);
             }
             else
             {
@@ -266,7 +265,7 @@ internal Task<Uri> BuildSuggestRequest(SuggestParameters parameters, Cancellatio
 
             if (parameters.SearchExtent != null)
             {
-                query.Add("searchExtent", parameters.SearchExtent.ToString());
+                query = query.Add("searchExtent", parameters.SearchExtent.ToString());
             }
             else
             {
@@ -275,7 +274,7 @@ internal Task<Uri> BuildSuggestRequest(SuggestParameters parameters, Cancellatio
 
             if (parameters.MaximumLocations > 0 && parameters.MaximumLocations < 16)
             {
-                query.Add("maxLocations", parameters.MaximumLocations.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("maxLocations", parameters.MaximumLocations.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -296,8 +295,8 @@ internal Task<Uri> BuildSuggestRequest(SuggestParameters parameters, Cancellatio
         internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters, CancellationToken cancellationToken)
         {
             var uriBuilder = new UriBuilder(ReverseGeocodingUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
-            query.Add("f", "json");
+            var query = QueryString.Empty;
+            query = query.Add("f", "json");
 
             if (parameters.Location is null)
             {
@@ -306,11 +305,11 @@ internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters
                 throw new ArgumentException(error, nameof(parameters.Location));
             }
 
-            query.Add("location", parameters.Location.ToString());
+            query = query.Add("location", parameters.Location.ToString());
 
             if (parameters.OutSpatialReference > 0)
             {
-                query.Add("outSR", parameters.OutSpatialReference.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("outSR", parameters.OutSpatialReference.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -319,7 +318,7 @@ internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters
 
             if (parameters.LanguageCode != null)
             {
-                query.Add("langCode", parameters.LanguageCode.TwoLetterISOLanguageName);
+                query = query.Add("langCode", parameters.LanguageCode.TwoLetterISOLanguageName);
             }
             else
             {
@@ -334,7 +333,7 @@ internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters
                     featureTypesBuilder.Add(featureType.ToEnumString<FeatureType>());
                 }
 
-                query.Add("featureTypes", featureTypesBuilder.ToString());
+                query = query.Add("featureTypes", featureTypesBuilder.ToString());
             }
             else
             {
@@ -343,7 +342,7 @@ internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters
 
             if (parameters.LocationType >= 0)
             {
-                query.Add("locationType", parameters.LocationType.ToEnumString<LocationType>());
+                query = query.Add("locationType", parameters.LocationType.ToEnumString<LocationType>());
             }
             else
             {
@@ -352,16 +351,16 @@ internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters
 
             if (parameters.PreferredLabelValue >= 0)
             {
-                query.Add("preferredLabelValues", parameters.PreferredLabelValue.ToEnumString<PreferredLabelValue>());
+                query = query.Add("preferredLabelValues", parameters.PreferredLabelValue.ToEnumString<PreferredLabelValue>());
             }
             else
             {
                 _logger.ArcGISWarning(_localizer["Invalid Preferred Label Value"]);
             }
 
-            AddStorageParameter(parameters, query);
+            AddStorageParameter(parameters, ref query);
 
-            await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
+            query = await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
 
             uriBuilder.Query = query.ToString();
 
@@ -377,8 +376,8 @@ internal async Task<Uri> BuildReverseGeocodingRequest(ReverseGeocodingParameters
         internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, CancellationToken cancellationToken)
         {
             var uriBuilder = new UriBuilder(GeocodingUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
-            query.Add("f", "json");
+            var query = QueryString.Empty;
+            query = query.Add("f", "json");
 
             if (parameters.AddressAttributes is null || parameters.AddressAttributes.Count == 0)
             {
@@ -402,15 +401,15 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
                 records = attributes,
             };
 
-            query.Add("addresses", JsonConvert.SerializeObject(addresses));
+            query = query.Add("addresses", JsonConvert.SerializeObject(addresses));
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("matchOutOfRange", parameters.MatchOutOfRange.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("matchOutOfRange", parameters.MatchOutOfRange.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
             if (!string.IsNullOrWhiteSpace(parameters.Category))
             {
-                query.Add("category", parameters.Category);
+                query = query.Add("category", parameters.Category);
             }
             else
             {
@@ -419,7 +418,7 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
 
             if (parameters.SourceCountry.Count != 0)
             {
-                query.Add("sourceCountry", string.Join(",", parameters.SourceCountry.Select(x => x.ThreeLetterISORegionName)));
+                query = query.Add("sourceCountry", string.Join(",", parameters.SourceCountry.Select(x => x.ThreeLetterISORegionName)));
             }
             else
             {
@@ -428,7 +427,7 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
 
             if (parameters.OutSpatialReference > 0)
             {
-                query.Add("outSR", parameters.OutSpatialReference.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("outSR", parameters.OutSpatialReference.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -437,7 +436,7 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
 
             if (parameters.SearchExtent != null)
             {
-                query.Add("searchExtent", parameters.SearchExtent.ToString());
+                query = query.Add("searchExtent", parameters.SearchExtent.ToString());
             }
             else
             {
@@ -446,7 +445,7 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
 
             if (parameters.LanguageCode != null)
             {
-                query.Add("langCode", parameters.LanguageCode.TwoLetterISOLanguageName);
+                query = query.Add("langCode", parameters.LanguageCode.TwoLetterISOLanguageName);
             }
             else
             {
@@ -455,7 +454,7 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
 
             if (parameters.LocationType >= 0)
             {
-                query.Add("locationType", parameters.LocationType.ToEnumString<LocationType>());
+                query = query.Add("locationType", parameters.LocationType.ToEnumString<LocationType>());
             }
             else
             {
@@ -464,14 +463,14 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
 
             if (parameters.PreferredLabelValue >= 0)
             {
-                query.Add("preferredLabelValues", parameters.PreferredLabelValue.ToEnumString<PreferredLabelValue>());
+                query = query.Add("preferredLabelValues", parameters.PreferredLabelValue.ToEnumString<PreferredLabelValue>());
             }
             else
             {
                 _logger.ArcGISWarning(_localizer["Invalid Preferred Label Value"]);
             }
 
-            await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
+            query = await AddArcGISToken(query, cancellationToken).ConfigureAwait(false);
 
             uriBuilder.Query = query.ToString();
 
@@ -482,11 +481,11 @@ internal async Task<Uri> BuildGeocodingRequest(GeocodingParameters parameters, C
         /// Adds the ArcGIS storage flag to the query parameters.
         /// </summary>
         /// <param name="parameters">A <see cref="StorageParameters"/> with the storage information.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddStorageParameter(StorageParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddStorageParameter(StorageParameters parameters, ref QueryString query)
         {
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("forStorage", parameters.ForStorage.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("forStorage", parameters.ForStorage.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
         }
 
@@ -494,16 +493,18 @@ internal void AddStorageParameter(StorageParameters parameters, NameValueCollect
         /// Adds the ArcGIS token to the query parameters.
         /// If the token cannot be generated, it will not be added to the request.
         /// </summary>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
         /// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the request.</param>
         /// <returns>A <see cref="Task"/>.</returns>
-        internal async Task AddArcGISToken(NameValueCollection query, CancellationToken cancellationToken)
+        internal async Task<QueryString> AddArcGISToken(QueryString query, CancellationToken cancellationToken)
         {
             var token = await _tokenContainer.GetTokenAsync(cancellationToken).ConfigureAwait(false);
             if (!string.IsNullOrWhiteSpace(token))
             {
-                query.Add("token", token);
+                return query.Add("token", token);
             }
+
+            return query;
         }
     }
 }
diff --git a/src/Geo.Bing/Services/BingGeocoding.cs b/src/Geo.Bing/Services/BingGeocoding.cs
index 76bffac..e3d3f93 100644
--- a/src/Geo.Bing/Services/BingGeocoding.cs
+++ b/src/Geo.Bing/Services/BingGeocoding.cs
@@ -6,18 +6,17 @@
 namespace Geo.Bing.Services
 {
     using System;
-    using System.Collections.Specialized;
     using System.Configuration;
     using System.Globalization;
     using System.Net.Http;
     using System.Threading;
     using System.Threading.Tasks;
-    using System.Web;
     using Geo.Bing.Abstractions;
     using Geo.Bing.Models.Exceptions;
     using Geo.Bing.Models.Parameters;
     using Geo.Bing.Models.Responses;
     using Geo.Core;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging;
     using Microsoft.Extensions.Logging.Abstractions;
@@ -120,7 +119,7 @@ internal Uri ValidateAndBuildUri<TParameters>(TParameters parameters, Func<TPara
         internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
         {
             var uriBuilder = new UriBuilder(BaseUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Query))
             {
@@ -129,11 +128,11 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Query));
             }
 
-            query.Add("query", parameters.Query);
+            query = query.Add("query", parameters.Query);
 
             BuildLimitedResultQuery(parameters, ref query);
 
-            AddBingKey(query);
+            AddBingKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -156,7 +155,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
             }
 
             var uriBuilder = new UriBuilder(BaseUri + $"/{parameters.Point}");
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             var includes = new CommaDelimitedStringCollection();
             if (parameters.IncludeAddress == true)
@@ -196,7 +195,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
 
             if (includes.Count > 0)
             {
-                query.Add("includeEntityTypes", includes.ToString());
+                query = query.Add("includeEntityTypes", includes.ToString());
             }
             else
             {
@@ -205,7 +204,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
 
             BuildBaseQuery(parameters, ref query);
 
-            AddBingKey(query);
+            AddBingKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -232,11 +231,11 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
             }
 
             var uriBuilder = new UriBuilder(BaseUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (!string.IsNullOrWhiteSpace(parameters.AdministrationDistrict))
             {
-                query.Add("adminDistrict", parameters.AdministrationDistrict);
+                query = query.Add("adminDistrict", parameters.AdministrationDistrict);
             }
             else
             {
@@ -245,7 +244,7 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.Locality))
             {
-                query.Add("locality", parameters.Locality);
+                query = query.Add("locality", parameters.Locality);
             }
             else
             {
@@ -254,7 +253,7 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.PostalCode))
             {
-                query.Add("postalCode", parameters.PostalCode);
+                query = query.Add("postalCode", parameters.PostalCode);
             }
             else
             {
@@ -263,7 +262,7 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.AddressLine))
             {
-                query.Add("addressLine", parameters.AddressLine);
+                query = query.Add("addressLine", parameters.AddressLine);
             }
             else
             {
@@ -272,7 +271,7 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
 
             if (parameters.CountryRegion != null)
             {
-                query.Add("countryRegion", parameters.CountryRegion.TwoLetterISORegionName.ToUpperInvariant());
+                query = query.Add("countryRegion", parameters.CountryRegion.TwoLetterISORegionName.ToUpperInvariant());
             }
             else
             {
@@ -281,7 +280,7 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
 
             BuildLimitedResultQuery(parameters, ref query);
 
-            AddBingKey(query);
+            AddBingKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -292,12 +291,12 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
         /// Builds up the limited result query parameters.
         /// </summary>
         /// <param name="parameters">A <see cref="ResultParameters"/> with the limited result parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the built up query parameters.</param>
-        internal void BuildLimitedResultQuery(ResultParameters parameters, ref NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the built up query parameters.</param>
+        internal void BuildLimitedResultQuery(ResultParameters parameters, ref QueryString query)
         {
             if (parameters.MaximumResults > 0 && parameters.MaximumResults <= 20)
             {
-                query.Add("maxResults", parameters.MaximumResults.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("maxResults", parameters.MaximumResults.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -311,12 +310,12 @@ internal void BuildLimitedResultQuery(ResultParameters parameters, ref NameValue
         /// Builds up the base query parameters.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseParameters"/> with the base parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the built up query parameters.</param>
-        internal void BuildBaseQuery(BaseParameters parameters, ref NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the built up query parameters.</param>
+        internal void BuildBaseQuery(BaseParameters parameters, ref QueryString query)
         {
             if (parameters.IncludeNeighbourhood == true)
             {
-                query.Add("includeNeighborhood", "1");
+                query = query.Add("includeNeighborhood", "1");
             }
             else
             {
@@ -336,7 +335,7 @@ internal void BuildBaseQuery(BaseParameters parameters, ref NameValueCollection
 
             if (includes.Count > 0)
             {
-                query.Add("include", includes.ToString());
+                query = query.Add("include", includes.ToString());
             }
             else
             {
@@ -347,10 +346,10 @@ internal void BuildBaseQuery(BaseParameters parameters, ref NameValueCollection
         /// <summary>
         /// Adds the Bing key to the query parameters.
         /// </summary>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBingKey(NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBingKey(ref QueryString query)
         {
-            query.Add("key", _keyContainer.GetKey());
+            query = query.Add("key", _keyContainer.GetKey());
         }
     }
 }
diff --git a/src/Geo.Google/Services/GoogleGeocoding.cs b/src/Geo.Google/Services/GoogleGeocoding.cs
index 6ffb976..4afed56 100644
--- a/src/Geo.Google/Services/GoogleGeocoding.cs
+++ b/src/Geo.Google/Services/GoogleGeocoding.cs
@@ -6,14 +6,12 @@
 namespace Geo.Google.Services
 {
     using System;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Linq;
     using System.Net.Http;
     using System.Text;
     using System.Threading;
     using System.Threading.Tasks;
-    using System.Web;
     using Geo.Core;
     using Geo.Core.Extensions;
     using Geo.Google.Abstractions;
@@ -22,6 +20,7 @@ namespace Geo.Google.Services
     using Geo.Google.Models.Exceptions;
     using Geo.Google.Models.Parameters;
     using Geo.Google.Models.Responses;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging;
     using Microsoft.Extensions.Logging.Abstractions;
@@ -182,7 +181,7 @@ internal Uri ValidateAndBuildUri<TParameters>(TParameters parameters, Func<TPara
         internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
         {
             var uriBuilder = new UriBuilder(GeocodingUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Address))
             {
@@ -191,11 +190,11 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Address));
             }
 
-            query.Add("address", parameters.Address);
+            query = query.Add("address", parameters.Address);
 
             if (parameters.Components != null)
             {
-                query.Add("components", parameters.Components.ToString());
+                query = query.Add("components", parameters.Components.ToString());
             }
             else
             {
@@ -206,7 +205,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
                 parameters.Bounds.Southwest != null &&
                 parameters.Bounds.Northeast != null)
             {
-                query.Add("bounds", parameters.Bounds.ToString());
+                query = query.Add("bounds", parameters.Bounds.ToString());
             }
             else
             {
@@ -215,16 +214,16 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
 
             if (parameters.Region != null)
             {
-                query.Add("region", RegionInfoToCCTLD(parameters.Region));
+                query = query.Add("region", RegionInfoToCCTLD(parameters.Region));
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid Region"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -240,7 +239,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
         internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
         {
             var uriBuilder = new UriBuilder(GeocodingUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (parameters.Coordinate is null)
             {
@@ -249,7 +248,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Coordinate));
             }
 
-            query.Add("latlng", parameters.Coordinate.ToString());
+            query = query.Add("latlng", parameters.Coordinate.ToString());
 
             if (parameters.ResultTypes != null)
             {
@@ -264,7 +263,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
                     resultTypesBuilder.Append(resultType.ToEnumString<ResultType>());
                 }
 
-                query.Add("result_type", resultTypesBuilder.ToString());
+                query = query.Add("result_type", resultTypesBuilder.ToString());
             }
             else
             {
@@ -284,16 +283,16 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
                     locationTypesBuilder.Append(locationType.ToEnumString<LocationType>());
                 }
 
-                query.Add("location_type", locationTypesBuilder.ToString());
+                query = query.Add("location_type", locationTypesBuilder.ToString());
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid Location Types"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -309,7 +308,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
         internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters)
         {
             var uriBuilder = new UriBuilder(FindPlaceUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Input))
             {
@@ -325,13 +324,13 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.InputType));
             }
 
-            query.Add("input", parameters.Input);
+            query = query.Add("input", parameters.Input);
 
-            query.Add("inputtype", parameters.InputType.ToEnumString());
+            query = query.Add("inputtype", parameters.InputType.ToEnumString());
 
             if (parameters.Fields != null && parameters.Fields.Count > 0)
             {
-                query.Add("fields", string.Join(",", parameters.Fields));
+                query = query.Add("fields", string.Join(",", parameters.Fields));
             }
             else
             {
@@ -343,13 +342,13 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters)
                 switch (parameters.LocationBias)
                 {
                     case Coordinate coordinate:
-                        query.Add("locationbias", $"point:{coordinate}");
+                        query = query.Add("locationbias", $"point:{coordinate}");
                         break;
                     case Circle circle:
-                        query.Add("locationbias", $"circle:{circle}");
+                        query = query.Add("locationbias", $"circle:{circle}");
                         break;
                     case Boundaries boundary:
-                        query.Add("locationbias", $"rectangle:{boundary}");
+                        query = query.Add("locationbias", $"rectangle:{boundary}");
                         break;
                     default:
                         _logger.GoogleWarning(_localizer["Invalid Location Bias Type"]);
@@ -361,9 +360,9 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters)
                 _logger.GoogleDebug(_localizer["Invalid Location Bias"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -383,7 +382,7 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters)
         internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters)
         {
             var uriBuilder = new UriBuilder(NearbySearchUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (parameters.Location == null)
             {
@@ -417,7 +416,7 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.Keyword))
             {
-                query.Add("keyword", parameters.Keyword);
+                query = query.Add("keyword", parameters.Keyword);
             }
             else
             {
@@ -426,16 +425,16 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters)
 
             if (parameters.RankBy >= RankType.Prominence && parameters.RankBy <= RankType.Distance)
             {
-                query.Add("rankby", parameters.RankBy.ToEnumString());
+                query = query.Add("rankby", parameters.RankBy.ToEnumString());
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid RankBy"]);
             }
 
-            AddBaseSearchParameters(parameters, query);
+            AddBaseSearchParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -451,7 +450,7 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters)
         internal Uri BuildTextSearchRequest(TextSearchParameters parameters)
         {
             var uriBuilder = new UriBuilder(TextSearchUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Query))
             {
@@ -460,20 +459,20 @@ internal Uri BuildTextSearchRequest(TextSearchParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Query));
             }
 
-            query.Add("query", parameters.Query);
+            query = query.Add("query", parameters.Query);
 
             if (parameters.Region != null)
             {
-                query.Add("region", RegionInfoToCCTLD(parameters.Region));
+                query = query.Add("region", RegionInfoToCCTLD(parameters.Region));
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid Region"]);
             }
 
-            AddBaseSearchParameters(parameters, query);
+            AddBaseSearchParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -489,7 +488,7 @@ internal Uri BuildTextSearchRequest(TextSearchParameters parameters)
         internal Uri BuildDetailsRequest(DetailsParameters parameters)
         {
             var uriBuilder = new UriBuilder(DetailsUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.PlaceId))
             {
@@ -498,11 +497,11 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.PlaceId));
             }
 
-            query.Add("place_id", parameters.PlaceId);
+            query = query.Add("place_id", parameters.PlaceId);
 
             if (parameters.Region != null)
             {
-                query.Add("region", RegionInfoToCCTLD(parameters.Region));
+                query = query.Add("region", RegionInfoToCCTLD(parameters.Region));
             }
             else
             {
@@ -511,7 +510,7 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.SessionToken))
             {
-                query.Add("sessiontoken", parameters.SessionToken);
+                query = query.Add("sessiontoken", parameters.SessionToken);
             }
             else
             {
@@ -520,16 +519,16 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters)
 
             if (parameters.Fields != null && parameters.Fields.Count > 0)
             {
-                query.Add("fields", string.Join(",", parameters.Fields));
+                query = query.Add("fields", string.Join(",", parameters.Fields));
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid Fields"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -545,7 +544,7 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters)
         internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters parameters)
         {
             var uriBuilder = new UriBuilder(PlaceAutocompleteUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Input))
             {
@@ -556,7 +555,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
 
             if (!string.IsNullOrWhiteSpace(parameters.SessionToken))
             {
-                query.Add("sessiontoken", parameters.SessionToken);
+                query = query.Add("sessiontoken", parameters.SessionToken);
             }
             else
             {
@@ -565,7 +564,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
 
             if (parameters.Origin != null)
             {
-                query.Add("origin", parameters.Origin.ToString());
+                query = query.Add("origin", parameters.Origin.ToString());
             }
             else
             {
@@ -574,7 +573,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
 
             if (parameters.Types != null && parameters.Types.Count > 0)
             {
-                query.Add("types", string.Join(",", parameters.Types.Select(x => x.ToEnumString())));
+                query = query.Add("types", string.Join(",", parameters.Types.Select(x => x.ToEnumString())));
             }
             else
             {
@@ -583,7 +582,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
 
             if (parameters.Components != null)
             {
-                query.Add("components", parameters.Components.ToString());
+                query = query.Add("components", parameters.Components.ToString());
             }
             else
             {
@@ -591,12 +590,12 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
             }
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("strictbounds", parameters.StrictBounds.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("strictbounds", parameters.StrictBounds.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
-            AddAutocompleteParameters(parameters, query);
+            AddAutocompleteParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -612,7 +611,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
         internal Uri BuildQueryAutocompleteRequest(QueryAutocompleteParameters parameters)
         {
             var uriBuilder = new UriBuilder(QueryAutocompleteUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Input))
             {
@@ -621,9 +620,9 @@ internal Uri BuildQueryAutocompleteRequest(QueryAutocompleteParameters parameter
                 throw new ArgumentException(error, nameof(parameters.Input));
             }
 
-            AddAutocompleteParameters(parameters, query);
+            AddAutocompleteParameters(parameters, ref query);
 
-            AddGoogleKey(query);
+            AddGoogleKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -634,12 +633,12 @@ internal Uri BuildQueryAutocompleteRequest(QueryAutocompleteParameters parameter
         /// Adds the autocomplete parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="QueryAutocompleteParameters"/> with the autocomplete parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddAutocompleteParameters(QueryAutocompleteParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddAutocompleteParameters(QueryAutocompleteParameters parameters, ref QueryString query)
         {
             if (parameters.Offset > 0)
             {
-                query.Add("offset", parameters.Offset.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("offset", parameters.Offset.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -648,26 +647,26 @@ internal void AddAutocompleteParameters(QueryAutocompleteParameters parameters,
 
             if (!string.IsNullOrWhiteSpace(parameters.Input))
             {
-                query.Add("input", parameters.Input);
+                query = query.Add("input", parameters.Input);
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid Input Info"]);
             }
 
-            AddCoordinateParameters(parameters, query);
+            AddCoordinateParameters(parameters, ref query);
         }
 
         /// <summary>
         /// Adds the base search parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseSearchParameters"/> with the base search parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBaseSearchParameters(BaseSearchParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBaseSearchParameters(BaseSearchParameters parameters, ref QueryString query)
         {
             if (parameters.MinimumPrice >= 0 && parameters.MinimumPrice <= 4 && parameters.MinimumPrice <= parameters.MaximumPrice)
             {
-                query.Add("minprice", parameters.MinimumPrice.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("minprice", parameters.MinimumPrice.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -676,7 +675,7 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, NameValue
 
             if (parameters.MaximumPrice >= 0 && parameters.MaximumPrice <= 4 && parameters.MinimumPrice <= parameters.MaximumPrice)
             {
-                query.Add("maxprice", parameters.MaximumPrice.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("maxprice", parameters.MaximumPrice.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -684,12 +683,12 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, NameValue
             }
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("opennow", parameters.OpenNow.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("opennow", parameters.OpenNow.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
             if (parameters.PageToken > 0)
             {
-                query.Add("pagetoken", parameters.PageToken.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("pagetoken", parameters.PageToken.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -698,26 +697,26 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, NameValue
 
             if (!string.IsNullOrWhiteSpace(parameters.Type))
             {
-                query.Add("type", parameters.Type);
+                query = query.Add("type", parameters.Type);
             }
             else
             {
                 _logger.GoogleDebug(_localizer["Invalid Type"]);
             }
 
-            AddCoordinateParameters(parameters, query);
+            AddCoordinateParameters(parameters, ref query);
         }
 
         /// <summary>
         /// Adds the coordinate parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="CoordinateParameters"/> with the coordinate parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddCoordinateParameters(CoordinateParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddCoordinateParameters(CoordinateParameters parameters, ref QueryString query)
         {
             if (parameters.Location != null)
             {
-                query.Add("location", parameters.Location.ToString());
+                query = query.Add("location", parameters.Location.ToString());
             }
             else
             {
@@ -726,26 +725,26 @@ internal void AddCoordinateParameters(CoordinateParameters parameters, NameValue
 
             if (parameters.Radius > 0 && parameters.Radius <= 50000)
             {
-                query.Add("radius", parameters.Radius.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("radius", parameters.Radius.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
                 _logger.GoogleWarning(_localizer["Invalid Radius Value"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
         }
 
         /// <summary>
         /// Adds the base query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseParameters"/> with the base parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBaseParameters(BaseParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBaseParameters(BaseParameters parameters, ref QueryString query)
         {
             if (parameters.Language != null)
             {
-                query.Add("language", parameters.Language.Name);
+                query = query.Add("language", parameters.Language.Name);
             }
             else
             {
@@ -756,10 +755,10 @@ internal void AddBaseParameters(BaseParameters parameters, NameValueCollection q
         /// <summary>
         /// Adds the Google key to the query parameters.
         /// </summary>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddGoogleKey(NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddGoogleKey(ref QueryString query)
         {
-            query.Add("key", _keyContainer.GetKey());
+            query = query.Add("key", _keyContainer.GetKey());
         }
 
         /// <summary>
diff --git a/src/Geo.Here/Services/HereGeocoding.cs b/src/Geo.Here/Services/HereGeocoding.cs
index 78dcf79..2d6a3db 100644
--- a/src/Geo.Here/Services/HereGeocoding.cs
+++ b/src/Geo.Here/Services/HereGeocoding.cs
@@ -6,18 +6,17 @@
 namespace Geo.Here.Services
 {
     using System;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Linq;
     using System.Net.Http;
     using System.Threading;
     using System.Threading.Tasks;
-    using System.Web;
     using Geo.Core;
     using Geo.Here.Abstractions;
     using Geo.Here.Models.Exceptions;
     using Geo.Here.Models.Parameters;
     using Geo.Here.Models.Responses;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging;
     using Microsoft.Extensions.Logging.Abstractions;
@@ -157,7 +156,7 @@ internal Uri ValidateAndBuildUri<TParameters>(TParameters parameters, Func<TPara
         internal Uri BuildGeocodingRequest(GeocodeParameters parameters)
         {
             var uriBuilder = new UriBuilder(GeocodeUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Query) && string.IsNullOrWhiteSpace(parameters.QualifiedQuery))
             {
@@ -168,7 +167,7 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.Query))
             {
-                query.Add("q", parameters.Query);
+                query = query.Add("q", parameters.Query);
             }
             else
             {
@@ -177,7 +176,7 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.QualifiedQuery))
             {
-                query.Add("qq", parameters.QualifiedQuery);
+                query = query.Add("qq", parameters.QualifiedQuery);
             }
             else
             {
@@ -186,16 +185,16 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters)
 
             if (parameters.InCountry.Count > 0)
             {
-                query.Add("in", string.Join(",", parameters.InCountry.Select(x => x.ThreeLetterISORegionName)));
+                query = query.Add("in", string.Join(",", parameters.InCountry.Select(x => x.ThreeLetterISORegionName)));
             }
             else
             {
                 _logger.HereDebug(_localizer["Invalid In Country"]);
             }
 
-            AddLocatingParameters(parameters, query);
+            AddLocatingParameters(parameters, ref query);
 
-            AddHereKey(query);
+            AddHereKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -211,7 +210,7 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters)
         internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters)
         {
             var uriBuilder = new UriBuilder(ReverseGeocodeUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (parameters.At is null)
             {
@@ -220,9 +219,9 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.At));
             }
 
-            AddLocatingParameters(parameters, query);
+            AddLocatingParameters(parameters, ref query);
 
-            AddHereKey(query);
+            AddHereKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -238,7 +237,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters)
         internal Uri BuildDiscoverRequest(DiscoverParameters parameters)
         {
             var uriBuilder = new UriBuilder(DiscoverUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Query))
             {
@@ -247,11 +246,11 @@ internal Uri BuildDiscoverRequest(DiscoverParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Query));
             }
 
-            query.Add("q", parameters.Query);
+            query = query.Add("q", parameters.Query);
 
-            AddBoundingParameters(parameters, query);
+            AddBoundingParameters(parameters, ref query);
 
-            AddHereKey(query);
+            AddHereKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -267,7 +266,7 @@ internal Uri BuildDiscoverRequest(DiscoverParameters parameters)
         internal Uri BuildAutosuggestRequest(AutosuggestParameters parameters)
         {
             var uriBuilder = new UriBuilder(AutosuggestUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Query))
             {
@@ -276,20 +275,20 @@ internal Uri BuildAutosuggestRequest(AutosuggestParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Query));
             }
 
-            query.Add("q", parameters.Query);
+            query = query.Add("q", parameters.Query);
 
             if (parameters.TermsLimit <= 10)
             {
-                query.Add("termsLimit", parameters.TermsLimit.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("termsLimit", parameters.TermsLimit.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
                 _logger.HereWarning(_localizer["Invalid Terms Limit"]);
             }
 
-            AddBoundingParameters(parameters, query);
+            AddBoundingParameters(parameters, ref query);
 
-            AddHereKey(query);
+            AddHereKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -305,7 +304,7 @@ internal Uri BuildAutosuggestRequest(AutosuggestParameters parameters)
         internal Uri BuildBrowseRequest(BrowseParameters parameters)
         {
             var uriBuilder = new UriBuilder(BrowseUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (parameters.At is null)
             {
@@ -316,7 +315,7 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.Categories))
             {
-                query.Add("categories", parameters.Categories);
+                query = query.Add("categories", parameters.Categories);
             }
             else
             {
@@ -325,16 +324,16 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters)
 
             if (!string.IsNullOrWhiteSpace(parameters.Name))
             {
-                query.Add("name", parameters.Name);
+                query = query.Add("name", parameters.Name);
             }
             else
             {
                 _logger.HereDebug(_localizer["Invalid Name"]);
             }
 
-            AddBoundingParameters(parameters, query);
+            AddBoundingParameters(parameters, ref query);
 
-            AddHereKey(query);
+            AddHereKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -350,7 +349,7 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters)
         internal Uri BuildLookupRequest(LookupParameters parameters)
         {
             var uriBuilder = new UriBuilder(LookupUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Id))
             {
@@ -359,11 +358,11 @@ internal Uri BuildLookupRequest(LookupParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Id));
             }
 
-            query.Add("id", parameters.Id);
+            query = query.Add("id", parameters.Id);
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddHereKey(query);
+            AddHereKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -374,8 +373,8 @@ internal Uri BuildLookupRequest(LookupParameters parameters)
         /// Adds the bounding query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="DiscoverParameters"/> with the bounding parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBoundingParameters(AreaParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBoundingParameters(AreaParameters parameters, ref QueryString query)
         {
             var hasAt = parameters.At != null && parameters.At.IsValid();
             var hasCircle = parameters.InCircle != null && parameters.InCircle.IsValid();
@@ -401,7 +400,7 @@ internal void AddBoundingParameters(AreaParameters parameters, NameValueCollecti
 
             if (hasAt)
             {
-                query.Add("at", parameters.At.ToString());
+                query = query.Add("at", parameters.At.ToString());
             }
             else
             {
@@ -410,7 +409,7 @@ internal void AddBoundingParameters(AreaParameters parameters, NameValueCollecti
 
             if (!string.IsNullOrWhiteSpace(parameters.InCountry))
             {
-                query.Add("in", $"countryCode:{parameters.InCountry}");
+                query = query.Add("in", $"countryCode:{parameters.InCountry}");
             }
             else
             {
@@ -419,7 +418,7 @@ internal void AddBoundingParameters(AreaParameters parameters, NameValueCollecti
 
             if (hasCircle)
             {
-                query.Add("in", $"circle:{parameters.InCircle}");
+                query = query.Add("in", $"circle:{parameters.InCircle}");
             }
             else
             {
@@ -428,7 +427,7 @@ internal void AddBoundingParameters(AreaParameters parameters, NameValueCollecti
 
             if (hasBoundingBox)
             {
-                query.Add("in", $"bbox:{parameters.InBoundingBox}");
+                query = query.Add("in", $"bbox:{parameters.InBoundingBox}");
             }
             else
             {
@@ -437,64 +436,64 @@ internal void AddBoundingParameters(AreaParameters parameters, NameValueCollecti
 
             if (!string.IsNullOrWhiteSpace(parameters.Route))
             {
-                query.Add("route", parameters.Route);
+                query = query.Add("route", parameters.Route);
             }
             else
             {
                 _logger.HereDebug(_localizer["Invalid Route"]);
             }
 
-            AddLimitingParameters(parameters, query);
+            AddLimitingParameters(parameters, ref query);
         }
 
         /// <summary>
         /// Adds the locating query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseFilterParameters"/> with the base limiting parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddLocatingParameters(BaseFilterParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddLocatingParameters(BaseFilterParameters parameters, ref QueryString query)
         {
             if (parameters.At != null)
             {
-                query.Add("at", parameters.At.ToString());
+                query = query.Add("at", parameters.At.ToString());
             }
             else
             {
                 _logger.HereDebug(_localizer["Invalid At Debug"]);
             }
 
-            AddLimitingParameters(parameters, query);
+            AddLimitingParameters(parameters, ref query);
         }
 
         /// <summary>
         /// Adds the base limiting query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseFilterParameters"/> with the base limiting parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddLimitingParameters(BaseFilterParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddLimitingParameters(BaseFilterParameters parameters, ref QueryString query)
         {
             if (parameters.Limit > 0 && parameters.Limit <= 100)
             {
-                query.Add("limit", parameters.Limit.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("limit", parameters.Limit.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
                 _logger.HereDebug(_localizer["Invalid Limit"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
         }
 
         /// <summary>
         /// Adds the base query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseParameters"/> with the base parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBaseParameters(BaseParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBaseParameters(BaseParameters parameters, ref QueryString query)
         {
             if (parameters.Language != null)
             {
-                query.Add("lang", parameters.Language.Name);
+                query = query.Add("lang", parameters.Language.Name);
             }
             else
             {
@@ -505,10 +504,10 @@ internal void AddBaseParameters(BaseParameters parameters, NameValueCollection q
         /// <summary>
         /// Adds the HERE key to the query parameters.
         /// </summary>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddHereKey(NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddHereKey(ref QueryString query)
         {
-            query.Add("apiKey", _keyContainer.GetKey());
+            query = query.Add("apiKey", _keyContainer.GetKey());
         }
     }
 }
diff --git a/src/Geo.MapBox/Services/MapBoxGeocoding.cs b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
index 4bd4925..421da7c 100644
--- a/src/Geo.MapBox/Services/MapBoxGeocoding.cs
+++ b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
@@ -7,7 +7,6 @@ namespace Geo.MapBox.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Linq;
     using System.Net.Http;
@@ -21,6 +20,7 @@ namespace Geo.MapBox.Services
     using Geo.MapBox.Models.Exceptions;
     using Geo.MapBox.Models.Parameters;
     using Geo.MapBox.Models.Responses;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging;
     using Microsoft.Extensions.Logging.Abstractions;
@@ -124,17 +124,16 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Query));
             }
 
-            var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, GeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, parameters.Query));
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
             var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, GeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, HttpUtility.UrlEncode(parameters.Query)));
+            var query = QueryString.Empty;
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("autocomplete", parameters.ReturnAutocomplete.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("autocomplete", parameters.ReturnAutocomplete.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
             if (parameters.BoundingBox != null)
             {
-                query.Add("bbox", parameters.BoundingBox.ToString());
+                query = query.Add("bbox", parameters.BoundingBox.ToString());
             }
             else
             {
@@ -142,21 +141,21 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
             }
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("fuzzyMatch", parameters.FuzzyMatch.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("fuzzyMatch", parameters.FuzzyMatch.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
             if (parameters.Proximity != null)
             {
-                query.Add("proximity", parameters.Proximity.ToString());
+                query = query.Add("proximity", parameters.Proximity.ToString());
             }
             else
             {
                 _logger.MapBoxDebug(_localizer["Invalid Proximity"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddMapBoxKey(query);
+            AddMapBoxKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -179,15 +178,15 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
             }
 
             var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, ReverseGeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, parameters.Coordinate));
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("reverseMode", parameters.ReverseMode.ToString().ToLowerInvariant());
+            query = query.Add("reverseMode", parameters.ReverseMode.ToString().ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddMapBoxKey(query);
+            AddMapBoxKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -198,12 +197,12 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
         /// Adds the base query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseParameters"/> with the base parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBaseParameters(BaseParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBaseParameters(BaseParameters parameters, ref QueryString query)
         {
             if (parameters.Countries.Count > 0)
             {
-                query.Add("country", string.Join(",", parameters.Countries.Select(x => x.TwoLetterISORegionName)));
+                query = query.Add("country", string.Join(",", parameters.Countries.Select(x => x.TwoLetterISORegionName)));
             }
             else
             {
@@ -212,7 +211,7 @@ internal void AddBaseParameters(BaseParameters parameters, NameValueCollection q
 
             if (parameters.Languages.Count > 0)
             {
-                query.Add("language", string.Join(",", parameters.Languages.Select(x => x.Name)));
+                query = query.Add("language", string.Join(",", parameters.Languages.Select(x => x.Name)));
             }
             else
             {
@@ -221,7 +220,7 @@ internal void AddBaseParameters(BaseParameters parameters, NameValueCollection q
 
             if (parameters.Limit > 0 && parameters.Limit < 6)
             {
-                query.Add("limit", parameters.Limit.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("limit", parameters.Limit.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -229,13 +228,13 @@ internal void AddBaseParameters(BaseParameters parameters, NameValueCollection q
             }
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("routing", parameters.Routing.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("routing", parameters.Routing.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
             if (parameters.Types != null && parameters.Types.Count > 0)
             {
 #pragma warning disable CA1308 // Normalize strings to uppercase
-                query.Add("types", string.Join(",", parameters.Types.Select(x => x.ToString().ToLowerInvariant())));
+                query = query.Add("types", string.Join(",", parameters.Types.Select(x => x.ToString().ToLowerInvariant())));
 #pragma warning restore CA1308 // Normalize strings to uppercase
             }
             else
@@ -247,10 +246,10 @@ internal void AddBaseParameters(BaseParameters parameters, NameValueCollection q
         /// <summary>
         /// Adds the here key to the query parameters.
         /// </summary>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddMapBoxKey(NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddMapBoxKey(ref QueryString query)
         {
-            query.Add("access_token", _keyContainer.GetKey());
+            query = query.Add("access_token", _keyContainer.GetKey());
         }
     }
 }
diff --git a/src/Geo.MapQuest/Services/MapQuestGeocoding.cs b/src/Geo.MapQuest/Services/MapQuestGeocoding.cs
index 2434cf1..c789bc4 100644
--- a/src/Geo.MapQuest/Services/MapQuestGeocoding.cs
+++ b/src/Geo.MapQuest/Services/MapQuestGeocoding.cs
@@ -6,18 +6,17 @@
 namespace Geo.MapQuest.Services
 {
     using System;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Net.Http;
     using System.Threading;
     using System.Threading.Tasks;
-    using System.Web;
     using Geo.Core;
     using Geo.MapQuest.Abstractions;
     using Geo.MapQuest.Enums;
     using Geo.MapQuest.Models.Exceptions;
     using Geo.MapQuest.Models.Parameters;
     using Geo.MapQuest.Models.Responses;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging;
     using Microsoft.Extensions.Logging.Abstractions;
@@ -119,7 +118,7 @@ internal Uri ValidateAndBuildUri<TParameters>(TParameters parameters, Func<TPara
         internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
         {
             var uriBuilder = new UriBuilder(_endpoint.UseLicensedEndpoint() ? GeocodeUri : OpenGeocodeUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (string.IsNullOrWhiteSpace(parameters.Location))
             {
@@ -128,13 +127,13 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Location));
             }
 
-            query.Add("location", parameters.Location);
+            query = query.Add("location", parameters.Location);
 
             if (!(parameters.BoundingBox is null) &&
                 (parameters.BoundingBox.East != 0 && parameters.BoundingBox.North != 0 &&
                 parameters.BoundingBox.West != 0 && parameters.BoundingBox.South != 0))
             {
-                query.Add("boundingBox", parameters.BoundingBox.ToString());
+                query = query.Add("boundingBox", parameters.BoundingBox.ToString());
             }
             else
             {
@@ -142,12 +141,12 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
             }
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("ignoreLatLngInput", parameters.IgnoreLatLngInput.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("ignoreLatLngInput", parameters.IgnoreLatLngInput.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
             if (parameters.MaxResults > 0)
             {
-                query.Add("maxResults", parameters.MaxResults.ToString(CultureInfo.InvariantCulture));
+                query = query.Add("maxResults", parameters.MaxResults.ToString(CultureInfo.InvariantCulture));
             }
             else
             {
@@ -156,24 +155,24 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
 
             if (parameters.IntlMode == InternationalMode.FiveBox)
             {
-                query.Add("intlMode", "5BOX");
+                query = query.Add("intlMode", "5BOX");
             }
             else if (parameters.IntlMode == InternationalMode.OneBox)
             {
-                query.Add("intlMode", "1BOX");
+                query = query.Add("intlMode", "1BOX");
             }
             else if (parameters.IntlMode == InternationalMode.Auto)
             {
-                query.Add("intlMode", "AUTO");
+                query = query.Add("intlMode", "AUTO");
             }
             else
             {
                 _logger.MapQuestWarning(_localizer["Invalid Intl Mode"]);
             }
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddMapQuestKey(query);
+            AddMapQuestKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -189,7 +188,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
         internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
         {
             var uriBuilder = new UriBuilder(_endpoint.UseLicensedEndpoint() ? ReverseGeocodeUri : OpenReverseGeocodeUri);
-            var query = HttpUtility.ParseQueryString(uriBuilder.Query);
+            var query = QueryString.Empty;
 
             if (parameters.Location is null)
             {
@@ -198,19 +197,19 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Location));
             }
 
-            query.Add("location", parameters.Location.ToString());
+            query = query.Add("location", parameters.Location.ToString());
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("includeNearestIntersection", parameters.IncludeNearestIntersection.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("includeNearestIntersection", parameters.IncludeNearestIntersection.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("includeRoadMetadata", parameters.IncludeRoadMetadata.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("includeRoadMetadata", parameters.IncludeRoadMetadata.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
 
-            AddBaseParameters(parameters, query);
+            AddBaseParameters(parameters, ref query);
 
-            AddMapQuestKey(query);
+            AddMapQuestKey(ref query);
 
             uriBuilder.Query = query.ToString();
 
@@ -221,21 +220,21 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
         /// Adds the base query parameters based on the allowed logic.
         /// </summary>
         /// <param name="parameters">A <see cref="BaseParameters"/> with the base parameters to build the uri with.</param>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddBaseParameters(BaseParameters parameters, NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddBaseParameters(BaseParameters parameters, ref QueryString query)
         {
 #pragma warning disable CA1308 // Normalize strings to uppercase
-            query.Add("thumbMaps", parameters.IncludeThumbMaps.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
+            query = query.Add("thumbMaps", parameters.IncludeThumbMaps.ToString(CultureInfo.InvariantCulture).ToLowerInvariant());
 #pragma warning restore CA1308 // Normalize strings to uppercase
         }
 
         /// <summary>
         /// Adds the MapQuest key to the query parameters.
         /// </summary>
-        /// <param name="query">A <see cref="NameValueCollection"/> with the query parameters.</param>
-        internal void AddMapQuestKey(NameValueCollection query)
+        /// <param name="query">A <see cref="QueryString"/> with the query parameters.</param>
+        internal void AddMapQuestKey(ref QueryString query)
         {
-            query.Add("key", _keyContainer.GetKey());
+            query = query.Add("key", _keyContainer.GetKey());
         }
     }
 }
diff --git a/src/Source.props b/src/Source.props
index 7e58f1c..a31909d 100644
--- a/src/Source.props
+++ b/src/Source.props
@@ -16,4 +16,13 @@
     <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
   </ItemGroup>
 
+
+  <ItemGroup Condition="'$(TargetFramework)' != 'netstandard2.1'">
+    <FrameworkReference Include="Microsoft.AspNetCore.App" />
+  </ItemGroup>
+
+  <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
+    <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
+  </ItemGroup>
+
 </Project>
diff --git a/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs b/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs
index f2eb1a2..66e2787 100644
--- a/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs
+++ b/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs
@@ -7,7 +7,6 @@ namespace Geo.ArcGIS.Tests.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Net;
     using System.Net.Http;
@@ -22,6 +21,7 @@ namespace Geo.ArcGIS.Tests.Services
     using Geo.ArcGIS.Models.Responses;
     using Geo.ArcGIS.Services;
     using Geo.Core;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging.Abstractions;
     using Microsoft.Extensions.Options;
@@ -164,11 +164,13 @@ public async Task AddArcGISTokenSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
 
-            await sut.AddArcGISToken(query, CancellationToken.None).ConfigureAwait(false);
-            query.Count.Should().Be(1);
-            query["token"].Should().Be("token123");
+            query = await sut.AddArcGISToken(query, CancellationToken.None).ConfigureAwait(false);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["token"].Should().Be("token123");
         }
 
         /// <summary>
@@ -179,25 +181,29 @@ public void AddStorageParameterSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new StorageParameters()
             {
                 ForStorage = false,
             };
 
-            sut.AddStorageParameter(parameters, query);
-            query.Count.Should().Be(1);
-            query["forStorage"].Should().Be("false");
+            sut.AddStorageParameter(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["forStorage"].Should().Be("false");
 
-            query.Clear();
+            query = QueryString.Empty;
             parameters = new StorageParameters()
             {
                 ForStorage = true,
             };
 
-            sut.AddStorageParameter(parameters, query);
-            query.Count.Should().Be(1);
-            query["forStorage"].Should().Be("true");
+            sut.AddStorageParameter(parameters, ref query);
+
+            queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["forStorage"].Should().Be("true");
         }
 
         /// <summary>
diff --git a/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs b/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs
index 4a7b57a..8eb1afa 100644
--- a/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs
+++ b/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs
@@ -7,7 +7,6 @@ namespace Geo.Bing.Tests.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Net;
     using System.Net.Http;
@@ -19,6 +18,7 @@ namespace Geo.Bing.Tests.Services
     using Geo.Bing.Models.Parameters;
     using Geo.Bing.Services;
     using Geo.Core;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging.Abstractions;
     using Microsoft.Extensions.Options;
@@ -148,11 +148,13 @@ public void AddBingKeySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
 
-            sut.AddBingKey(query);
-            query.Count.Should().Be(1);
-            query["key"].Should().Be("123abc");
+            sut.AddBingKey(ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["key"].Should().Be("123abc");
         }
 
         /// <summary>
@@ -163,7 +165,7 @@ public void BuildBaseQuerySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseParameters()
             {
                 IncludeNeighbourhood = true,
@@ -172,9 +174,11 @@ public void BuildBaseQuerySuccessfully()
             };
 
             sut.BuildBaseQuery(parameters, ref query);
-            query.Count.Should().Be(2);
-            query["includeNeighborhood"].Should().Be("1");
-            query["include"].Should().Contain("queryParse").And.Contain("ciso2");
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(2);
+            queryParameters["includeNeighborhood"].Should().Be("1");
+            queryParameters["include"].Should().Contain("queryParse").And.Contain("ciso2");
         }
 
         /// <summary>
@@ -185,7 +189,7 @@ public void BuildLimitedResultQuerySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new ResultParameters()
             {
                 MaximumResults = 7,
@@ -195,10 +199,12 @@ public void BuildLimitedResultQuerySuccessfully()
             };
 
             sut.BuildLimitedResultQuery(parameters, ref query);
-            query.Count.Should().Be(3);
-            query["maxResults"].Should().Be("7");
-            query["includeNeighborhood"].Should().Be("1");
-            query["include"].Should().Contain("queryParse").And.Contain("ciso2");
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["maxResults"].Should().Be("7");
+            queryParameters["includeNeighborhood"].Should().Be("1");
+            queryParameters["include"].Should().Contain("queryParse").And.Contain("ciso2");
         }
 
         /// <summary>
diff --git a/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs b/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs
index 187fc13..d991ebb 100644
--- a/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs
+++ b/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs
@@ -7,7 +7,6 @@ namespace Geo.Google.Tests.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Linq;
     using System.Net;
@@ -22,6 +21,7 @@ namespace Geo.Google.Tests.Services
     using Geo.Google.Models;
     using Geo.Google.Models.Parameters;
     using Geo.Google.Services;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging.Abstractions;
     using Microsoft.Extensions.Options;
@@ -124,11 +124,13 @@ public void AddGoogleKeySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
 
-            sut.AddGoogleKey(query);
-            query.Count.Should().Be(1);
-            query["key"].Should().Be("abc123");
+            sut.AddGoogleKey(ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["key"].Should().Be("abc123");
         }
 
         /// <summary>
@@ -139,15 +141,17 @@ public void AddBaseParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseParameters()
             {
                 Language = new CultureInfo("da"),
             };
 
-            sut.AddBaseParameters(parameters, query);
-            query.Count.Should().Be(1);
-            query["language"].Should().Be("da");
+            sut.AddBaseParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["language"].Should().Be("da");
         }
 
         /// <summary>
@@ -158,7 +162,7 @@ public void AddCoordinateParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new CoordinateParameters()
             {
                 Location = new Coordinate()
@@ -170,11 +174,13 @@ public void AddCoordinateParametersSuccessfully()
                 Language = new CultureInfo("da"),
             };
 
-            sut.AddCoordinateParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["location"].Should().Be("76.54,34.56");
-            query["radius"].Should().Be("10000");
-            query["language"].Should().Be("da");
+            sut.AddCoordinateParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["location"].Should().Be("76.54,34.56");
+            queryParameters["radius"].Should().Be("10000");
+            queryParameters["language"].Should().Be("da");
         }
 
         /// <summary>
@@ -185,7 +191,7 @@ public void AddBaseSearchParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseSearchParameters()
             {
                 MinimumPrice = 2,
@@ -202,16 +208,18 @@ public void AddBaseSearchParametersSuccessfully()
                 Language = new CultureInfo("pt-BR"),
             };
 
-            sut.AddBaseSearchParameters(parameters, query);
-            query.Count.Should().Be(8);
-            query["minprice"].Should().Be("2");
-            query["maxprice"].Should().Be("3");
-            query["opennow"].Should().Be("false");
-            query["pagetoken"].Should().Be("987654");
-            query["type"].Should().Be("Restaurant");
-            query["location"].Should().Be("76.14,34.54");
-            query["radius"].Should().Be("10001");
-            query["language"].Should().Be("pt-BR");
+            sut.AddBaseSearchParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(8);
+            queryParameters["minprice"].Should().Be("2");
+            queryParameters["maxprice"].Should().Be("3");
+            queryParameters["opennow"].Should().Be("false");
+            queryParameters["pagetoken"].Should().Be("987654");
+            queryParameters["type"].Should().Be("Restaurant");
+            queryParameters["location"].Should().Be("76.14,34.54");
+            queryParameters["radius"].Should().Be("10001");
+            queryParameters["language"].Should().Be("pt-BR");
         }
 
         /// <summary>
@@ -222,7 +230,7 @@ public void AddAutocompleteParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new QueryAutocompleteParameters()
             {
                 Offset = 64,
@@ -236,13 +244,15 @@ public void AddAutocompleteParametersSuccessfully()
                 Language = new CultureInfo("fr"),
             };
 
-            sut.AddAutocompleteParameters(parameters, query);
-            query.Count.Should().Be(5);
-            query["offset"].Should().Be("64");
-            query["input"].Should().Be("123 East");
-            query["location"].Should().Be("6.14,3.54");
-            query["radius"].Should().Be("25000");
-            query["language"].Should().Be("fr");
+            sut.AddAutocompleteParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(5);
+            queryParameters["offset"].Should().Be("64");
+            queryParameters["input"].Should().Be("123 East");
+            queryParameters["location"].Should().Be("6.14,3.54");
+            queryParameters["radius"].Should().Be("25000");
+            queryParameters["language"].Should().Be("fr");
         }
 
         /// <summary>
@@ -253,7 +263,7 @@ public void AddBaseSearchParametersWithRestrictions1()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseSearchParameters()
             {
                 MinimumPrice = 5,
@@ -268,11 +278,13 @@ public void AddBaseSearchParametersWithRestrictions1()
                 Language = new CultureInfo("es"),
             };
 
-            sut.AddBaseSearchParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["opennow"].Should().Be("false");
-            query["location"].Should().Be("76.14,34.54");
-            query["language"].Should().Be("es");
+            sut.AddBaseSearchParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["opennow"].Should().Be("false");
+            queryParameters["location"].Should().Be("76.14,34.54");
+            queryParameters["language"].Should().Be("es");
         }
 
         /// <summary>
@@ -283,7 +295,7 @@ public void AddBaseSearchParametersWithRestrictions2()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseSearchParameters()
             {
                 MinimumPrice = 3,
@@ -298,11 +310,13 @@ public void AddBaseSearchParametersWithRestrictions2()
                 Language = new CultureInfo("es"),
             };
 
-            sut.AddBaseSearchParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["opennow"].Should().Be("false");
-            query["location"].Should().Be("76.14,34.54");
-            query["language"].Should().Be("es");
+            sut.AddBaseSearchParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["opennow"].Should().Be("false");
+            queryParameters["location"].Should().Be("76.14,34.54");
+            queryParameters["language"].Should().Be("es");
         }
 
         /// <summary>
diff --git a/test/Geo.Here.Tests/Services/HereGeocodingShould.cs b/test/Geo.Here.Tests/Services/HereGeocodingShould.cs
index dc3ccf4..c1c70b3 100644
--- a/test/Geo.Here.Tests/Services/HereGeocodingShould.cs
+++ b/test/Geo.Here.Tests/Services/HereGeocodingShould.cs
@@ -7,7 +7,6 @@ namespace Geo.Here.Tests.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Net;
     using System.Net.Http;
@@ -20,6 +19,7 @@ namespace Geo.Here.Tests.Services
     using Geo.Here.Models.Exceptions;
     using Geo.Here.Models.Parameters;
     using Geo.Here.Services;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging.Abstractions;
     using Microsoft.Extensions.Options;
@@ -192,11 +192,13 @@ public void AddHereKeySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
 
-            sut.AddHereKey(query);
-            query.Count.Should().Be(1);
-            query["apiKey"].Should().Be("abc123");
+            sut.AddHereKey(ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["apiKey"].Should().Be("abc123");
         }
 
         /// <summary>
@@ -207,15 +209,17 @@ public void AddBaseParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseParameters()
             {
                 Language = new CultureInfo("es"),
             };
 
-            sut.AddBaseParameters(parameters, query);
-            query.Count.Should().Be(1);
-            query["lang"].Should().Be("es");
+            sut.AddBaseParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["lang"].Should().Be("es");
         }
 
         /// <summary>
@@ -226,17 +230,19 @@ public void AddLimitingParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseFilterParameters()
             {
                 Limit = 17,
                 Language = new CultureInfo("da"),
             };
 
-            sut.AddLimitingParameters(parameters, query);
-            query.Count.Should().Be(2);
-            query["limit"].Should().Be("17");
-            query["lang"].Should().Be("da");
+            sut.AddLimitingParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(2);
+            queryParameters["limit"].Should().Be("17");
+            queryParameters["lang"].Should().Be("da");
         }
 
         /// <summary>
@@ -247,7 +253,7 @@ public void AddLocatingParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseFilterParameters()
             {
                 At = new Coordinate()
@@ -259,11 +265,13 @@ public void AddLocatingParametersSuccessfully()
                 Language = new CultureInfo("fr-FR"),
             };
 
-            sut.AddLocatingParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["at"].Should().Be("56.789,123.456");
-            query["limit"].Should().Be("91");
-            query["lang"].Should().Be("fr-FR");
+            sut.AddLocatingParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["at"].Should().Be("56.789,123.456");
+            queryParameters["limit"].Should().Be("91");
+            queryParameters["lang"].Should().Be("fr-FR");
         }
 
         /// <summary>
@@ -274,7 +282,7 @@ public void AddBoundingParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new AreaParameters()
             {
                 At = new Coordinate()
@@ -286,13 +294,15 @@ public void AddBoundingParametersSuccessfully()
                 Language = new CultureInfo("fr"),
             };
 
-            sut.AddBoundingParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["at"].Should().Be("56.789,123.456");
-            query["limit"].Should().Be("91");
-            query["lang"].Should().Be("fr");
+            sut.AddBoundingParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["at"].Should().Be("56.789,123.456");
+            queryParameters["limit"].Should().Be("91");
+            queryParameters["lang"].Should().Be("fr");
 
-            query.Clear();
+            query = QueryString.Empty;
             parameters = new AreaParameters()
             {
                 InCountry = "BEL",
@@ -305,14 +315,16 @@ public void AddBoundingParametersSuccessfully()
                 Language = new CultureInfo("nl"),
             };
 
-            sut.AddBoundingParameters(parameters, query);
-            query.Count.Should().Be(4);
-            query["in"].Should().Be("countryCode:BEL");
-            query["at"].Should().Be("56.789,123.456");
-            query["limit"].Should().Be("91");
-            query["lang"].Should().Be("nl");
+            sut.AddBoundingParameters(parameters, ref query);
 
-            query.Clear();
+            queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(4);
+            queryParameters["in"].Should().Be("countryCode:BEL");
+            queryParameters["at"].Should().Be("56.789,123.456");
+            queryParameters["limit"].Should().Be("91");
+            queryParameters["lang"].Should().Be("nl");
+
+            query = QueryString.Empty;
             parameters = new AreaParameters()
             {
                 InCircle = new Circle()
@@ -328,13 +340,15 @@ public void AddBoundingParametersSuccessfully()
                 Language = new CultureInfo("gl"),
             };
 
-            sut.AddBoundingParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["in"].Should().Be("circle:78.9,45.32;r=50000");
-            query["limit"].Should().Be("83");
-            query["lang"].Should().Be("gl");
+            sut.AddBoundingParameters(parameters, ref query);
+
+            queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["in"].Should().Be("circle:78.9,45.32;r=50000");
+            queryParameters["limit"].Should().Be("83");
+            queryParameters["lang"].Should().Be("gl");
 
-            query.Clear();
+            query = QueryString.Empty;
             parameters = new AreaParameters()
             {
                 InCountry = "DNK",
@@ -351,13 +365,15 @@ public void AddBoundingParametersSuccessfully()
                 Language = new CultureInfo("da"),
             };
 
-            sut.AddBoundingParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["in"].Should().Be("countryCode:DNK,circle:48.9,15.32;r=6000");
-            query["limit"].Should().Be("48");
-            query["lang"].Should().Be("da");
+            sut.AddBoundingParameters(parameters, ref query);
+
+            queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["in"].Should().Be("countryCode:DNK,circle:48.9,15.32;r=6000");
+            queryParameters["limit"].Should().Be("48");
+            queryParameters["lang"].Should().Be("da");
 
-            query.Clear();
+            query = QueryString.Empty;
             parameters = new AreaParameters()
             {
                 InBoundingBox = new BoundingBox()
@@ -371,13 +387,15 @@ public void AddBoundingParametersSuccessfully()
                 Language = new CultureInfo("ca"),
             };
 
-            sut.AddBoundingParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["in"].Should().Be("bbox:-1.5,87.99,1.5,89.99");
-            query["limit"].Should().Be("65");
-            query["lang"].Should().Be("ca");
+            sut.AddBoundingParameters(parameters, ref query);
 
-            query.Clear();
+            queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["in"].Should().Be("bbox:-1.5,87.99,1.5,89.99");
+            queryParameters["limit"].Should().Be("65");
+            queryParameters["lang"].Should().Be("ca");
+
+            query = QueryString.Empty;
             parameters = new AreaParameters()
             {
                 InCountry = "POL",
@@ -392,11 +410,13 @@ public void AddBoundingParametersSuccessfully()
                 Language = new CultureInfo("pl"),
             };
 
-            sut.AddBoundingParameters(parameters, query);
-            query.Count.Should().Be(3);
-            query["in"].Should().Be("countryCode:POL,bbox:-43.5,45.99,-39.5,54.99");
-            query["limit"].Should().Be("33");
-            query["lang"].Should().Be("pl");
+            sut.AddBoundingParameters(parameters, ref query);
+
+            queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(3);
+            queryParameters["in"].Should().Be("countryCode:POL,bbox:-43.5,45.99,-39.5,54.99");
+            queryParameters["limit"].Should().Be("33");
+            queryParameters["lang"].Should().Be("pl");
         }
 
         /// <summary>
@@ -407,8 +427,8 @@ public void AddBoundingParametersWithException()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
-            Action act = () => sut.AddBoundingParameters(new AreaParameters(), query);
+            var query = QueryString.Empty;
+            Action act = () => sut.AddBoundingParameters(new AreaParameters(), ref query);
 
             act.Should()
                 .Throw<ArgumentException>()
@@ -442,7 +462,7 @@ public void AddBoundingParametersWithException()
                 Language = new CultureInfo("pl"),
             };
 
-            act = () => sut.AddBoundingParameters(new AreaParameters(), query);
+            act = () => sut.AddBoundingParameters(new AreaParameters(), ref query);
 
             act.Should()
                 .Throw<ArgumentException>()
diff --git a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
index c97b9ad..679f036 100644
--- a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
+++ b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
@@ -7,7 +7,6 @@ namespace Geo.MapBox.Tests.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Globalization;
     using System.Net;
     using System.Net.Http;
@@ -21,6 +20,7 @@ namespace Geo.MapBox.Tests.Services
     using Geo.MapBox.Models.Exceptions;
     using Geo.MapBox.Models.Parameters;
     using Geo.MapBox.Services;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging.Abstractions;
     using Microsoft.Extensions.Options;
@@ -113,11 +113,13 @@ public void AddMapBoxKeySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
 
-            sut.AddMapBoxKey(query);
-            query.Count.Should().Be(1);
-            query["access_token"].Should().Be("abc123");
+            sut.AddMapBoxKey(ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["access_token"].Should().Be("abc123");
         }
 
         /// <summary>
@@ -128,7 +130,7 @@ public void AddBaseParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseParameters()
             {
                 Limit = 5,
@@ -144,13 +146,15 @@ public void AddBaseParametersSuccessfully()
             parameters.Types.Add(FeatureType.Address);
             parameters.Types.Add(FeatureType.Place);
 
-            sut.AddBaseParameters(parameters, query);
-            query.Count.Should().Be(5);
-            query["country"].Should().Be("CA,FR");
-            query["language"].Should().Be("en,fr-FR");
-            query["limit"].Should().Be("5");
-            query["routing"].Should().Be("true");
-            query["types"].Should().Be("address,place");
+            sut.AddBaseParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(5);
+            queryParameters["country"].Should().Be("CA,FR");
+            queryParameters["language"].Should().Be("en,fr-FR");
+            queryParameters["limit"].Should().Be("5");
+            queryParameters["routing"].Should().Be("true");
+            queryParameters["types"].Should().Be("address,place");
         }
 
         /// <summary>
diff --git a/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs b/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs
index 6a437e4..df79b88 100644
--- a/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs
+++ b/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs
@@ -7,7 +7,6 @@ namespace Geo.MapQuest.Tests.Services
 {
     using System;
     using System.Collections.Generic;
-    using System.Collections.Specialized;
     using System.Net;
     using System.Net.Http;
     using System.Threading;
@@ -20,6 +19,7 @@ namespace Geo.MapQuest.Tests.Services
     using Geo.MapQuest.Models.Exceptions;
     using Geo.MapQuest.Models.Parameters;
     using Geo.MapQuest.Services;
+    using Microsoft.AspNetCore.Http;
     using Microsoft.Extensions.Localization;
     using Microsoft.Extensions.Logging.Abstractions;
     using Microsoft.Extensions.Options;
@@ -125,11 +125,13 @@ public void AddMapBoxKeySuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
 
-            sut.AddMapQuestKey(query);
-            query.Count.Should().Be(1);
-            query["key"].Should().Be("abc123");
+            sut.AddMapQuestKey(ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["key"].Should().Be("abc123");
         }
 
         /// <summary>
@@ -140,15 +142,17 @@ public void AddBaseParametersSuccessfully()
         {
             var sut = BuildService();
 
-            var query = new NameValueCollection();
+            var query = QueryString.Empty;
             var parameters = new BaseParameters()
             {
                 IncludeThumbMaps = true,
             };
 
-            sut.AddBaseParameters(parameters, query);
-            query.Count.Should().Be(1);
-            query["thumbMaps"].Should().Be("true");
+            sut.AddBaseParameters(parameters, ref query);
+
+            var queryParameters = HttpUtility.ParseQueryString(query.ToString());
+            queryParameters.Count.Should().Be(1);
+            queryParameters["thumbMaps"].Should().Be("true");
         }
 
         /// <summary>

From 40e796c8d43fa9b610afca868a763515c32f3bfc Mon Sep 17 00:00:00 2001
From: JustinCanton <67930245+JustinCanton@users.noreply.github.com>
Date: Thu, 18 Aug 2022 19:13:36 -0400
Subject: [PATCH 3/4] test(mapbox-geocoding): adding tests for encoding of
 query information

---
 .../Services/MapBoxGeocodingShould.cs         | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
index 679f036..47c6bc9 100644
--- a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
+++ b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
@@ -213,6 +213,29 @@ public void BuildGeocodingRequestSuccessfully()
             path.Should().Contain("mapbox.places/123 East");
         }
 
+        [Fact]
+        public void BuildGeocodingRequest_WithCharacterNeedingEncoding_SuccessfullyBuildsAnEncodedUrl()
+        {
+            var sut = BuildService();
+
+            var parameters = new GeocodingParameters()
+            {
+                Query = "123 East #425",
+                Limit = 5,
+                Routing = true,
+            };
+
+            var uri = sut.BuildGeocodingRequest(parameters);
+            var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+            query.Should().Contain("limit=5");
+            query.Should().Contain("routing=true");
+            query.Should().Contain("access_token=abc123");
+
+            var path = HttpUtility.UrlDecode(uri.AbsolutePath);
+            path.Should().Contain("mapbox.places/123 East #425");
+            uri.AbsolutePath.Should().Contain("mapbox.places/123+East+%23425");
+        }
+
         /// <summary>
         /// Tests the building of the geocoding parameters fails if no query is provided.
         /// </summary>

From f98a4bcc439e4a6ac027565d0ebf4ba305c8a573 Mon Sep 17 00:00:00 2001
From: JustinCanton <67930245+JustinCanton@users.noreply.github.com>
Date: Thu, 18 Aug 2022 19:21:51 -0400
Subject: [PATCH 4/4] feat(mapbox-geocoding): changing the encoding method to
 UrlEncoder for consistency

---
 src/Geo.MapBox/Services/MapBoxGeocoding.cs              | 4 ++--
 test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/Geo.MapBox/Services/MapBoxGeocoding.cs b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
index 421da7c..7054b57 100644
--- a/src/Geo.MapBox/Services/MapBoxGeocoding.cs
+++ b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
@@ -10,9 +10,9 @@ namespace Geo.MapBox.Services
     using System.Globalization;
     using System.Linq;
     using System.Net.Http;
+    using System.Text.Encodings.Web;
     using System.Threading;
     using System.Threading.Tasks;
-    using System.Web;
     using Geo.Core;
     using Geo.MapBox.Abstractions;
     using Geo.MapBox.Enums;
@@ -124,7 +124,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
                 throw new ArgumentException(error, nameof(parameters.Query));
             }
 
-            var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, GeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, HttpUtility.UrlEncode(parameters.Query)));
+            var uriBuilder = new UriBuilder(string.Format(CultureInfo.InvariantCulture, GeocodeUri, parameters.EndpointType == EndpointType.Places ? PlacesEndpoint : PermanentEndpoint, UrlEncoder.Default.Encode(parameters.Query)));
             var query = QueryString.Empty;
 
 #pragma warning disable CA1308 // Normalize strings to uppercase
diff --git a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
index 47c6bc9..cbfd5f7 100644
--- a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
+++ b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
@@ -233,7 +233,7 @@ public void BuildGeocodingRequest_WithCharacterNeedingEncoding_SuccessfullyBuild
 
             var path = HttpUtility.UrlDecode(uri.AbsolutePath);
             path.Should().Contain("mapbox.places/123 East #425");
-            uri.AbsolutePath.Should().Contain("mapbox.places/123+East+%23425");
+            uri.AbsolutePath.Should().Contain("mapbox.places/123%20East%20%23425");
         }
 
         /// <summary>