From 4863a3538fa3dfed79bcdfe3ffca5c5598e91085 Mon Sep 17 00:00:00 2001
From: JustinCanton <67930245+JustinCanton@users.noreply.github.com>
Date: Fri, 27 Feb 2026 21:32:57 -0500
Subject: [PATCH] feat: adding an AdditionalParameters property to specify
anything the user may want outside of what is in the current parameters
---
clean-bin-and-obj.bat | 15 ++
.../Models/Parameters/GeocodingParameters.cs | 5 +-
.../Models/Parameters/StorageParameters.cs | 7 +-
.../Models/Parameters/SuggestParameters.cs | 5 +-
src/Geo.ArcGIS/Services/ArcGISGeocoding.cs | 6 +
.../Models/Parameters/BaseParameters.cs | 6 +-
src/Geo.Bing/Services/BingGeocoding.cs | 3 +
.../Abstractions/IAdditionalParameters.cs | 20 +++
.../Extensions/QueryStringExtensions.cs | 42 +++++
.../Models/Parameters/BaseParameters.cs | 6 +-
src/Geo.Google/Services/GoogleGeocoding.cs | 8 +
.../Models/Parameters/BaseParameters.cs | 5 +-
src/Geo.Here/Services/HereGeocoding.cs | 6 +
.../Models/Parameters/BaseParameters.cs | 5 +-
src/Geo.MapBox/Services/MapBoxGeocoding.cs | 2 +
.../Models/Parameters/BaseParameters.cs | 7 +-
.../Services/MapQuestGeocoding.cs | 2 +
.../Models/Parameters/GeocodingParameters.cs | 5 +-
.../Parameters/ReverseGeocodingParameters.cs | 5 +-
.../Services/PositionstackGeocoding.cs | 2 +
.../Parameters/AutocompleteParameters.cs | 5 +-
.../Models/Parameters/GeocodingParameters.cs | 5 +-
.../Parameters/ReverseGeocodingParameters.cs | 5 +-
src/Geo.Radar/Services/RadarGeocoding.cs | 3 +
.../Services/ArcGISGeocodingShould.cs | 100 ++++++++++++
.../Services/BingGeocodingShould.cs | 63 +++++++-
.../Extensions/QueryStringExtensionsShould.cs | 151 ++++++++++++++++++
.../Services/GoogleGeocodingShould.cs | 23 +++
.../Services/HereGeocodingShould.cs | 132 +++++++++++++++
.../Services/MapBoxGeocodingShould.cs | 44 ++++-
.../Services/MapQuestGeocodingShould.cs | 44 ++++-
.../Services/PositionstackGeocodingShould.cs | 44 ++++-
.../Services/RadarGeocodingShould.cs | 63 +++++++-
33 files changed, 826 insertions(+), 18 deletions(-)
create mode 100644 clean-bin-and-obj.bat
create mode 100644 src/Geo.Core/Abstractions/IAdditionalParameters.cs
create mode 100644 src/Geo.Core/Extensions/QueryStringExtensions.cs
create mode 100644 test/Geo.Core.Tests/Extensions/QueryStringExtensionsShould.cs
diff --git a/clean-bin-and-obj.bat b/clean-bin-and-obj.bat
new file mode 100644
index 0000000..f0b158d
--- /dev/null
+++ b/clean-bin-and-obj.bat
@@ -0,0 +1,15 @@
+@Echo Off
+FOR /d /r .\ %%d IN (*) DO (
+ @IF EXIST "%%d" (
+ pushd %%d
+ FOR /d /r %%t IN (bin\, obj\) DO (
+ @IF EXIST "%%t" (
+ ECHO "Removing %%t"
+ rd /s /q "%%t"
+ )
+ )
+ popd
+ )
+)
+
+pause
\ No newline at end of file
diff --git a/src/Geo.ArcGIS/Models/Parameters/GeocodingParameters.cs b/src/Geo.ArcGIS/Models/Parameters/GeocodingParameters.cs
index da8483e..1f29650 100644
--- a/src/Geo.ArcGIS/Models/Parameters/GeocodingParameters.cs
+++ b/src/Geo.ArcGIS/Models/Parameters/GeocodingParameters.cs
@@ -12,7 +12,7 @@ namespace Geo.ArcGIS.Models.Parameters
///
/// A parameters object for the geocoding ArcGIS request.
///
- public class GeocodingParameters : IClientCredentialsParameters
+ public class GeocodingParameters : IClientCredentialsParameters, IAdditionalParameters
{
///
/// Gets a list of address attributes.
@@ -85,5 +85,8 @@ public class GeocodingParameters : IClientCredentialsParameters
///
public string ClientSecret { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.ArcGIS/Models/Parameters/StorageParameters.cs b/src/Geo.ArcGIS/Models/Parameters/StorageParameters.cs
index 9a73f06..a2b7306 100644
--- a/src/Geo.ArcGIS/Models/Parameters/StorageParameters.cs
+++ b/src/Geo.ArcGIS/Models/Parameters/StorageParameters.cs
@@ -5,10 +5,12 @@
namespace Geo.ArcGIS.Models.Parameters
{
+ using System.Collections.Generic;
+
///
/// A parameters object for the storage flag information in ArcGIS request.
///
- public class StorageParameters
+ public class StorageParameters : IAdditionalParameters
{
///
/// Gets or sets a value indicating whether the results of the operation will be persisted.
@@ -31,5 +33,8 @@ public class StorageParameters
/// (https://developers.arcgis.com/rest/geocode/api-reference/geocoding-free-vs-paid.htm).
///
public bool ForStorage { get; set; } = false;
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.ArcGIS/Models/Parameters/SuggestParameters.cs b/src/Geo.ArcGIS/Models/Parameters/SuggestParameters.cs
index 9e88127..6c7bc80 100644
--- a/src/Geo.ArcGIS/Models/Parameters/SuggestParameters.cs
+++ b/src/Geo.ArcGIS/Models/Parameters/SuggestParameters.cs
@@ -13,7 +13,7 @@ namespace Geo.ArcGIS.Models.Parameters
///
/// A parameters object for the suggest ArcGIS request.
///
- public class SuggestParameters
+ public class SuggestParameters : IAdditionalParameters
{
///
/// Gets or sets the input text entered by a user, which is used by the suggest operation to generate a list of possible matches.
@@ -65,5 +65,8 @@ public class SuggestParameters
/// The default value is postal city.
///
public PreferredLabelValue PreferredLabelValue { get; set; } = PreferredLabelValue.PostalCity;
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs b/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs
index c113377..aaf79fc 100644
--- a/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs
+++ b/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs
@@ -420,6 +420,7 @@ internal async Task BuildAddressCandidateRequest(AddressCandidateParameters
AddStorageParameter(parameters, ref query);
query = await AddArcGISToken(parameters, query, cancellationToken).ConfigureAwait(false);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -597,6 +598,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par
AddStorageParameter(parameters, ref query);
query = await AddArcGISToken(parameters, query, cancellationToken).ConfigureAwait(false);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -686,6 +688,8 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio
_logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Preferred_Label_Value);
}
+ query = query.AddAdditionalParameters(parameters);
+
uriBuilder.AddQuery(query);
return Task.FromResult(uriBuilder.Uri);
@@ -765,6 +769,7 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters
AddStorageParameter(parameters, ref query);
query = await AddArcGISToken(parameters, query, cancellationToken).ConfigureAwait(false);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -884,6 +889,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C
}
query = await AddArcGISToken(parameters, query, cancellationToken).ConfigureAwait(false);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.Bing/Models/Parameters/BaseParameters.cs b/src/Geo.Bing/Models/Parameters/BaseParameters.cs
index dd57fca..769d124 100644
--- a/src/Geo.Bing/Models/Parameters/BaseParameters.cs
+++ b/src/Geo.Bing/Models/Parameters/BaseParameters.cs
@@ -5,12 +5,13 @@
namespace Geo.Bing.Models.Parameters
{
+ using System.Collections.Generic;
using System.Globalization;
///
/// Base parameters across all Bing geocoding APIs.
///
- public class BaseParameters
+ public class BaseParameters : IAdditionalParameters
{
///
/// Gets or sets a value indicating whether or not to include the neighbourhood information.
@@ -34,5 +35,8 @@ public class BaseParameters
/// Gets or sets the culture to use for the request.
///
public CultureInfo Culture { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Bing/Services/BingGeocoding.cs b/src/Geo.Bing/Services/BingGeocoding.cs
index bc8d3ca..8e67ef8 100644
--- a/src/Geo.Bing/Services/BingGeocoding.cs
+++ b/src/Geo.Bing/Services/BingGeocoding.cs
@@ -126,6 +126,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
BuildLimitedResultQuery(parameters, ref query);
AddBingKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -197,6 +198,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
BuildBaseQuery(parameters, ref query);
AddBingKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -272,6 +274,7 @@ internal Uri BuildAddressGeocodingRequest(AddressGeocodingParameters parameters)
BuildLimitedResultQuery(parameters, ref query);
AddBingKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.Core/Abstractions/IAdditionalParameters.cs b/src/Geo.Core/Abstractions/IAdditionalParameters.cs
new file mode 100644
index 0000000..58e07ce
--- /dev/null
+++ b/src/Geo.Core/Abstractions/IAdditionalParameters.cs
@@ -0,0 +1,20 @@
+//
+// Copyright (c) Geo.NET.
+// Licensed under the MIT license. See the LICENSE file in the solution root for full license information.
+//
+
+namespace Geo
+{
+ using System.Collections.Generic;
+
+ ///
+ /// Parameters that allow additional key/value pairs to be appended to the request query string.
+ ///
+ public interface IAdditionalParameters
+ {
+ ///
+ /// Gets the additional key/value pairs to be appended to the request query string.
+ ///
+ IDictionary AdditionalParameters { get; }
+ }
+}
diff --git a/src/Geo.Core/Extensions/QueryStringExtensions.cs b/src/Geo.Core/Extensions/QueryStringExtensions.cs
new file mode 100644
index 0000000..6b7ad25
--- /dev/null
+++ b/src/Geo.Core/Extensions/QueryStringExtensions.cs
@@ -0,0 +1,42 @@
+//
+// Copyright (c) Geo.NET.
+// Licensed under the MIT license. See the LICENSE file in the solution root for full license information.
+//
+
+namespace Geo.Core.Extensions
+{
+ using Geo;
+
+ ///
+ /// Extension methods on the struct.
+ ///
+ public static class QueryStringExtensions
+ {
+ ///
+ /// Adds any additional parameters from an instance to the .
+ /// Entries with a null value are skipped.
+ ///
+ /// The to add to.
+ /// The to read additional key/value pairs from.
+ /// The with the additional parameters appended.
+ public static QueryString AddAdditionalParameters(this QueryString query, IAdditionalParameters parameters)
+ {
+ if (parameters?.AdditionalParameters == null)
+ {
+ return query;
+ }
+
+ foreach (var kvp in parameters.AdditionalParameters)
+ {
+ if (kvp.Value == null)
+ {
+ continue;
+ }
+
+ query = query.Add(kvp.Key, kvp.Value);
+ }
+
+ return query;
+ }
+ }
+}
diff --git a/src/Geo.Google/Models/Parameters/BaseParameters.cs b/src/Geo.Google/Models/Parameters/BaseParameters.cs
index 6001dbe..b023520 100644
--- a/src/Geo.Google/Models/Parameters/BaseParameters.cs
+++ b/src/Geo.Google/Models/Parameters/BaseParameters.cs
@@ -5,16 +5,20 @@
namespace Geo.Google.Models.Parameters
{
+ using System.Collections.Generic;
using System.Globalization;
///
/// The base parameters shared across all requests.
///
- public class BaseParameters
+ public class BaseParameters : IAdditionalParameters
{
///
/// Gets or sets the language in which to return results.
///
public CultureInfo Language { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Google/Services/GoogleGeocoding.cs b/src/Geo.Google/Services/GoogleGeocoding.cs
index 000ed1a..159d050 100644
--- a/src/Geo.Google/Services/GoogleGeocoding.cs
+++ b/src/Geo.Google/Services/GoogleGeocoding.cs
@@ -235,6 +235,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
AddBaseParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -303,6 +304,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
AddBaseParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -371,6 +373,7 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters)
AddBaseParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -439,6 +442,7 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters)
AddBaseSearchParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -476,6 +480,7 @@ internal Uri BuildTextSearchRequest(TextSearchParameters parameters)
AddBaseSearchParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -531,6 +536,7 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters)
AddBaseParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -597,6 +603,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete
AddAutocompleteParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -623,6 +630,7 @@ internal Uri BuildQueryAutocompleteRequest(QueryAutocompleteParameters parameter
AddAutocompleteParameters(parameters, ref query);
AddGoogleKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.Here/Models/Parameters/BaseParameters.cs b/src/Geo.Here/Models/Parameters/BaseParameters.cs
index 9947342..8385d4f 100644
--- a/src/Geo.Here/Models/Parameters/BaseParameters.cs
+++ b/src/Geo.Here/Models/Parameters/BaseParameters.cs
@@ -11,7 +11,7 @@ namespace Geo.Here.Models.Parameters
///
/// The base parameters that are used with all HERE requests.
///
- public class BaseParameters
+ public class BaseParameters : IAdditionalParameters
{
///
/// Gets or sets the language to be used for result rendering from a list of BCP47 compliant Language Codes.
@@ -36,5 +36,8 @@ public class BaseParameters
///
///
public IList Show { get; } = new List();
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Here/Services/HereGeocoding.cs b/src/Geo.Here/Services/HereGeocoding.cs
index c2304ae..d06fc1c 100644
--- a/src/Geo.Here/Services/HereGeocoding.cs
+++ b/src/Geo.Here/Services/HereGeocoding.cs
@@ -197,6 +197,7 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters)
AddLocatingParameters(parameters, ref query);
AddHereKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -242,6 +243,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters)
AddLocatingParameters(parameters, ref query);
AddHereKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -270,6 +272,7 @@ internal Uri BuildDiscoverRequest(DiscoverParameters parameters)
AddBoundingParameters(parameters, ref query);
AddHereKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -307,6 +310,7 @@ internal Uri BuildAutosuggestRequest(AutosuggestParameters parameters)
AddBoundingParameters(parameters, ref query);
AddHereKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -351,6 +355,7 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters)
AddBoundingParameters(parameters, ref query);
AddHereKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -379,6 +384,7 @@ internal Uri BuildLookupRequest(LookupParameters parameters)
AddBaseParameters(parameters, ref query);
AddHereKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.MapBox/Models/Parameters/BaseParameters.cs b/src/Geo.MapBox/Models/Parameters/BaseParameters.cs
index 3f3bc79..e5f5f57 100644
--- a/src/Geo.MapBox/Models/Parameters/BaseParameters.cs
+++ b/src/Geo.MapBox/Models/Parameters/BaseParameters.cs
@@ -12,7 +12,7 @@ namespace Geo.MapBox.Models.Parameters
///
/// The parameters possible to use for all requests.
///
- public class BaseParameters
+ public class BaseParameters : IAdditionalParameters
{
///
/// Gets or sets the type of endpoint to call.
@@ -52,5 +52,8 @@ public class BaseParameters
/// Available worldviews are: ar,cn,in,jp,ma,ru,tr,us. If worldview is not set, the us worldview boundaries are returned by default.
///
public string Worldview { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.MapBox/Services/MapBoxGeocoding.cs b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
index 9ed5c8a..1e356b9 100644
--- a/src/Geo.MapBox/Services/MapBoxGeocoding.cs
+++ b/src/Geo.MapBox/Services/MapBoxGeocoding.cs
@@ -149,6 +149,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
AddBaseParameters(parameters, ref query);
AddMapBoxKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -179,6 +180,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
AddBaseParameters(parameters, ref query);
AddMapBoxKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.MapQuest/Models/Parameters/BaseParameters.cs b/src/Geo.MapQuest/Models/Parameters/BaseParameters.cs
index b7f4cfa..812b307 100644
--- a/src/Geo.MapQuest/Models/Parameters/BaseParameters.cs
+++ b/src/Geo.MapQuest/Models/Parameters/BaseParameters.cs
@@ -5,15 +5,20 @@
namespace Geo.MapQuest.Models.Parameters
{
+ using System.Collections.Generic;
+
///
/// The base parameters used across all requests.
///
- public class BaseParameters
+ public class BaseParameters : IAdditionalParameters
{
///
/// Gets or sets a value indicating whether a URL to a static map thumbnail image for a location being geocoded should be returned.
/// Default is true.
///
public bool IncludeThumbMaps { get; set; } = true;
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.MapQuest/Services/MapQuestGeocoding.cs b/src/Geo.MapQuest/Services/MapQuestGeocoding.cs
index 913762a..d9eabd8 100644
--- a/src/Geo.MapQuest/Services/MapQuestGeocoding.cs
+++ b/src/Geo.MapQuest/Services/MapQuestGeocoding.cs
@@ -175,6 +175,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
AddBaseParameters(parameters, ref query);
AddMapQuestKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -211,6 +212,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
AddBaseParameters(parameters, ref query);
AddMapQuestKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.Positionstack/Models/Parameters/GeocodingParameters.cs b/src/Geo.Positionstack/Models/Parameters/GeocodingParameters.cs
index 4ee2df7..071f1ac 100644
--- a/src/Geo.Positionstack/Models/Parameters/GeocodingParameters.cs
+++ b/src/Geo.Positionstack/Models/Parameters/GeocodingParameters.cs
@@ -11,7 +11,7 @@ namespace Geo.Positionstack.Models.Parameters
///
/// The parameters possible to use during a geocoding request.
///
- public class GeocodingParameters : ILocationGeocodeParameters, IFilterGeocodeParameters, IKeyParameters
+ public class GeocodingParameters : ILocationGeocodeParameters, IFilterGeocodeParameters, IKeyParameters, IAdditionalParameters
{
///
/// Gets or sets the address to geocode.
@@ -47,5 +47,8 @@ public class GeocodingParameters : ILocationGeocodeParameters, IFilterGeocodePar
///
public string Key { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Positionstack/Models/Parameters/ReverseGeocodingParameters.cs b/src/Geo.Positionstack/Models/Parameters/ReverseGeocodingParameters.cs
index 8229f8b..439356c 100644
--- a/src/Geo.Positionstack/Models/Parameters/ReverseGeocodingParameters.cs
+++ b/src/Geo.Positionstack/Models/Parameters/ReverseGeocodingParameters.cs
@@ -11,7 +11,7 @@ namespace Geo.Positionstack.Models.Parameters
///
/// The parameters possible to use during a reverse geocoding request.
///
- public class ReverseGeocodingParameters : ILocationGeocodeParameters, IFilterGeocodeParameters, IKeyParameters
+ public class ReverseGeocodingParameters : ILocationGeocodeParameters, IFilterGeocodeParameters, IKeyParameters, IAdditionalParameters
{
///
/// Gets or sets the coordinates to reverse geocode.
@@ -47,5 +47,8 @@ public class ReverseGeocodingParameters : ILocationGeocodeParameters, IFilterGeo
///
public string Key { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Positionstack/Services/PositionstackGeocoding.cs b/src/Geo.Positionstack/Services/PositionstackGeocoding.cs
index ece407b..2718f6b 100644
--- a/src/Geo.Positionstack/Services/PositionstackGeocoding.cs
+++ b/src/Geo.Positionstack/Services/PositionstackGeocoding.cs
@@ -119,6 +119,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
AddFilterParameters(parameters, ref query);
AddLocationParameters(parameters, ref query);
AddPositionstackKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -147,6 +148,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
AddFilterParameters(parameters, ref query);
AddLocationParameters(parameters, ref query);
AddPositionstackKey(parameters, ref query);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/src/Geo.Radar/Models/Parameters/AutocompleteParameters.cs b/src/Geo.Radar/Models/Parameters/AutocompleteParameters.cs
index a63abed..f06f9ef 100644
--- a/src/Geo.Radar/Models/Parameters/AutocompleteParameters.cs
+++ b/src/Geo.Radar/Models/Parameters/AutocompleteParameters.cs
@@ -10,7 +10,7 @@ namespace Geo.Radar.Models.Parameters
///
/// The parameters possible to use during an autocomplete request.
///
- public class AutocompleteParameters : ICountryParameter, ILayersParameter, IKeyParameters
+ public class AutocompleteParameters : ICountryParameter, ILayersParameter, IKeyParameters, IAdditionalParameters
{
///
/// Gets or sets the partial address or place name to autocomplete.
@@ -40,5 +40,8 @@ public class AutocompleteParameters : ICountryParameter, ILayersParameter, IKeyP
///
public string Key { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Radar/Models/Parameters/GeocodingParameters.cs b/src/Geo.Radar/Models/Parameters/GeocodingParameters.cs
index c2acbb8..198bb78 100644
--- a/src/Geo.Radar/Models/Parameters/GeocodingParameters.cs
+++ b/src/Geo.Radar/Models/Parameters/GeocodingParameters.cs
@@ -11,7 +11,7 @@ namespace Geo.Radar.Models.Parameters
///
/// The parameters possible to use during a geocoding request.
///
- public class GeocodingParameters : ICountryParameter, ILayersParameter, IKeyParameters
+ public class GeocodingParameters : ICountryParameter, ILayersParameter, IKeyParameters, IAdditionalParameters
{
///
/// Gets or sets the address to geocode.
@@ -26,5 +26,8 @@ public class GeocodingParameters : ICountryParameter, ILayersParameter, IKeyPara
///
public string Key { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Radar/Models/Parameters/ReverseGeocodingParameters.cs b/src/Geo.Radar/Models/Parameters/ReverseGeocodingParameters.cs
index 784a65c..cf8ff54 100644
--- a/src/Geo.Radar/Models/Parameters/ReverseGeocodingParameters.cs
+++ b/src/Geo.Radar/Models/Parameters/ReverseGeocodingParameters.cs
@@ -11,7 +11,7 @@ namespace Geo.Radar.Models.Parameters
///
/// The parameters possible to use during a reverse geocoding request.
///
- public class ReverseGeocodingParameters : ILayersParameter, IKeyParameters
+ public class ReverseGeocodingParameters : ILayersParameter, IKeyParameters, IAdditionalParameters
{
///
/// Gets or sets the coordinates to reverse geocode.
@@ -23,5 +23,8 @@ public class ReverseGeocodingParameters : ILayersParameter, IKeyParameters
///
public string Key { get; set; }
+
+ ///
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
}
}
diff --git a/src/Geo.Radar/Services/RadarGeocoding.cs b/src/Geo.Radar/Services/RadarGeocoding.cs
index c840bed..4c08f05 100644
--- a/src/Geo.Radar/Services/RadarGeocoding.cs
+++ b/src/Geo.Radar/Services/RadarGeocoding.cs
@@ -131,6 +131,7 @@ internal Uri BuildGeocodingRequest(GeocodingParameters parameters)
AddCountry(parameters, ref query);
AddLayers(parameters, ref query);
AddRadarKey(parameters);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -158,6 +159,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodingParameters parameters)
AddLayers(parameters, ref query);
AddRadarKey(parameters);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
@@ -206,6 +208,7 @@ internal Uri BuildAutocompleteRequest(AutocompleteParameters parameters)
AddCountry(parameters, ref query);
AddLayers(parameters, ref query);
AddRadarKey(parameters);
+ query = query.AddAdditionalParameters(parameters);
uriBuilder.AddQuery(query);
diff --git a/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs b/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs
index 2c05353..3b99871 100644
--- a/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs
+++ b/test/Geo.ArcGIS.Tests/Services/ArcGISGeocodingShould.cs
@@ -278,6 +278,25 @@ public void BuildAddressCandidateRequestWithException()
#endif
}
+ [Fact]
+ public async Task BuildAddressCandidateRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new AddressCandidateParameters()
+ {
+ SingleLineAddress = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = await sut.BuildAddressCandidateRequest(parameters, CancellationToken.None);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the place candidate uri is built properly.
///
@@ -321,6 +340,22 @@ public async Task BuildPlaceCandidateRequestSuccessfully(CultureInfo culture)
Thread.CurrentThread.CurrentCulture = oldCulture;
}
+ [Fact]
+ public async Task BuildPlaceCandidateRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new PlaceCandidateParameters();
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = await sut.BuildPlaceCandidateRequest(parameters, CancellationToken.None);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the findAddressCandidates uri is built properly using a single-line address.
///
@@ -526,6 +561,25 @@ public void BuildSuggestRequestWithException()
#endif
}
+ [Fact]
+ public async Task BuildSuggestRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new SuggestParameters()
+ {
+ Text = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = await sut.BuildSuggestRequest(parameters, CancellationToken.None);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the reverse geocoding uri is built properly.
///
@@ -594,6 +648,29 @@ public void BuildReverseGeocodingRequestWithException()
#endif
}
+ [Fact]
+ public async Task BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodingParameters()
+ {
+ Location = new Coordinate()
+ {
+ Latitude = 80.012,
+ Longitude = 123.456,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = await sut.BuildReverseGeocodingRequest(parameters, CancellationToken.None);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the geocoding uri is built properly.
///
@@ -675,6 +752,29 @@ public void BuildGeocodingRequestWithException()
#endif
}
+ [Fact]
+ public async Task BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters();
+
+ parameters.AddressAttributes.Add(
+ new AddressAttributeParameter()
+ {
+ ObjectId = 1,
+ SingleLine = "123 East",
+ });
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = await sut.BuildGeocodingRequest(parameters, CancellationToken.None);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the geocoding uri includes outFields when the parameter is set.
///
diff --git a/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs b/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs
index b9a7a12..67b97c0 100644
--- a/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs
+++ b/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs
@@ -295,6 +295,25 @@ public void BuildGeocodingRequestSuccessfully(CultureInfo culture)
Thread.CurrentThread.CurrentCulture = oldCulture;
}
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters()
+ {
+ Query = "1 Microsoft Way Redmond WA",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the reverse geocoding uri isn't built if a point isn't passed in.
///
@@ -361,6 +380,29 @@ public void BuildReverseGeocodingRequestSuccessfully(CultureInfo culture)
Thread.CurrentThread.CurrentCulture = oldCulture;
}
+ [Fact]
+ public void BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodingParameters()
+ {
+ Point = new Coordinate()
+ {
+ Latitude = 40.7567,
+ Longitude = -73.9897,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildReverseGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the address geocoding uri isn't built if not enought information is passed in.
///
@@ -425,6 +467,25 @@ public void BuildAddressGeocodingRequestSuccessfully(CultureInfo culture)
Thread.CurrentThread.CurrentCulture = oldCulture;
}
+ [Fact]
+ public void BuildAddressGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new AddressGeocodingParameters()
+ {
+ AddressLine = "222 Bay Street",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildAddressGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the geocoding returns a response successfully.
///
@@ -520,4 +581,4 @@ private BingGeocoding BuildService()
return new BingGeocoding(_httpClient, _options.Object);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Geo.Core.Tests/Extensions/QueryStringExtensionsShould.cs b/test/Geo.Core.Tests/Extensions/QueryStringExtensionsShould.cs
new file mode 100644
index 0000000..a3a2be8
--- /dev/null
+++ b/test/Geo.Core.Tests/Extensions/QueryStringExtensionsShould.cs
@@ -0,0 +1,151 @@
+//
+// Copyright (c) Geo.NET.
+// Licensed under the MIT license. See the LICENSE file in the solution root for full license information.
+//
+
+namespace Geo.Core.Tests.Extensions
+{
+ using System.Collections.Generic;
+ using FluentAssertions;
+ using Geo.Core.Extensions;
+ using Xunit;
+
+ ///
+ /// Unit tests for the class.
+ ///
+ public class QueryStringExtensionsShould
+ {
+ private class TestAdditionalParameters : IAdditionalParameters
+ {
+ public IDictionary AdditionalParameters { get; } = new Dictionary();
+ }
+
+ private class NullDictionaryAdditionalParameters : IAdditionalParameters
+ {
+#pragma warning disable CS8603 // Possible null reference return.
+ public IDictionary AdditionalParameters => null;
+#pragma warning restore CS8603 // Possible null reference return.
+ }
+
+ ///
+ /// Tests that a null parameters object causes the original query to be returned unchanged.
+ ///
+ [Fact]
+ public void ReturnUnchangedQueryString_WhenParametersIsNull()
+ {
+ var query = QueryString.Empty.Add("existing", "value");
+
+ var result = query.AddAdditionalParameters(null);
+
+ result.Should().Be(query);
+ }
+
+ ///
+ /// Tests that a null AdditionalParameters dictionary causes the original query to be returned unchanged.
+ ///
+ [Fact]
+ public void ReturnUnchangedQueryString_WhenAdditionalParametersDictionaryIsNull()
+ {
+ var query = QueryString.Empty.Add("existing", "value");
+ var parameters = new NullDictionaryAdditionalParameters();
+
+ var result = query.AddAdditionalParameters(parameters);
+
+ result.Should().Be(query);
+ }
+
+ ///
+ /// Tests that an empty AdditionalParameters dictionary causes the original query to be returned unchanged.
+ ///
+ [Fact]
+ public void ReturnUnchangedQueryString_WhenAdditionalParametersDictionaryIsEmpty()
+ {
+ var query = QueryString.Empty.Add("existing", "value");
+ var parameters = new TestAdditionalParameters();
+
+ var result = query.AddAdditionalParameters(parameters);
+
+ result.Should().Be(query);
+ }
+
+ ///
+ /// Tests that a single additional key/value pair is appended to the query string.
+ ///
+ [Fact]
+ public void AddSingleKeyValuePair_ToQueryString()
+ {
+ var parameters = new TestAdditionalParameters();
+ parameters.AdditionalParameters.Add("key1", "value1");
+
+ var result = QueryString.Empty.AddAdditionalParameters(parameters);
+
+ result.Value.Should().Contain("key1=value1");
+ }
+
+ ///
+ /// Tests that multiple additional key/value pairs are all appended to the query string.
+ ///
+ [Fact]
+ public void AddMultipleKeyValuePairs_ToQueryString()
+ {
+ var parameters = new TestAdditionalParameters();
+ parameters.AdditionalParameters.Add("key1", "value1");
+ parameters.AdditionalParameters.Add("key2", "value2");
+ parameters.AdditionalParameters.Add("key3", "value3");
+
+ var result = QueryString.Empty.AddAdditionalParameters(parameters);
+
+ result.Value.Should().Contain("key1=value1");
+ result.Value.Should().Contain("key2=value2");
+ result.Value.Should().Contain("key3=value3");
+ }
+
+ ///
+ /// Tests that an entry with a null value is skipped and not appended to the query string.
+ ///
+ [Fact]
+ public void SkipEntry_WhenValueIsNull()
+ {
+ var parameters = new TestAdditionalParameters();
+ parameters.AdditionalParameters.Add("nullkey", null);
+
+ var result = QueryString.Empty.AddAdditionalParameters(parameters);
+
+ result.Should().Be(QueryString.Empty);
+ }
+
+ ///
+ /// Tests that only null-valued entries are skipped while non-null entries are added.
+ ///
+ [Fact]
+ public void SkipOnlyNullValueEntries_WhenMixedWithNonNullValues()
+ {
+ var parameters = new TestAdditionalParameters();
+ parameters.AdditionalParameters.Add("key1", "value1");
+ parameters.AdditionalParameters.Add("nullkey", null);
+ parameters.AdditionalParameters.Add("key3", "value3");
+
+ var result = QueryString.Empty.AddAdditionalParameters(parameters);
+
+ result.Value.Should().Contain("key1=value1");
+ result.Value.Should().NotContain("nullkey");
+ result.Value.Should().Contain("key3=value3");
+ }
+
+ ///
+ /// Tests that additional parameters are appended after existing query parameters.
+ ///
+ [Fact]
+ public void AppendAdditionalParameters_AfterExistingQueryParameters()
+ {
+ var query = QueryString.Empty.Add("existing", "value");
+ var parameters = new TestAdditionalParameters();
+ parameters.AdditionalParameters.Add("extra", "data");
+
+ var result = query.AddAdditionalParameters(parameters);
+
+ result.Value.Should().Contain("existing=value");
+ result.Value.Should().Contain("extra=data");
+ }
+ }
+}
diff --git a/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs b/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs
index 48e9da4..13521cc 100644
--- a/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs
+++ b/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs
@@ -1047,6 +1047,29 @@ protected virtual void Dispose(bool disposing)
_disposed = true;
}
+ ///
+ /// Tests the additional parameters are properly included in the geocoding request uri.
+ ///
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_IncludesThemInUri()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters()
+ {
+ Address = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("custom_param", "custom_value");
+ parameters.AdditionalParameters.Add("version", "2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("custom_param=custom_value");
+ query.Should().Contain("version=2");
+ }
+
private GoogleGeocoding BuildService()
{
return new GoogleGeocoding(_httpClient, _options.Object);
diff --git a/test/Geo.Here.Tests/Services/HereGeocodingShould.cs b/test/Geo.Here.Tests/Services/HereGeocodingShould.cs
index f14131b..a97ee3f 100644
--- a/test/Geo.Here.Tests/Services/HereGeocodingShould.cs
+++ b/test/Geo.Here.Tests/Services/HereGeocodingShould.cs
@@ -714,6 +714,25 @@ public void BuildGeocodingRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodeParameters()
+ {
+ Query = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the building of the reverse geocoding parameters is done successfully.
///
@@ -814,6 +833,29 @@ public void BuildReverseGeocodingRequestFailsWithException()
///
/// Tests the building of the reverse geocoding parameters fails if no query is provided.
///
+ [Fact]
+ public void BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodeParameters()
+ {
+ At = new Coordinate()
+ {
+ Latitude = 56.78,
+ Longitude = 78.91,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildReverseGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
[Fact]
public void BuildReverseGeocodingRequest_WithBothInAndAt_FailsWithException()
{
@@ -910,6 +952,30 @@ public void BuildDiscoverRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildDiscoverRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new DiscoverParameters()
+ {
+ Query = "123 East",
+ At = new Coordinate()
+ {
+ Latitude = 54.2,
+ Longitude = 45.2,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildDiscoverRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the building of the autosuggest parameters is done successfully.
///
@@ -975,6 +1041,30 @@ public void BuildAutosuggestRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildAutosuggestRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new AutosuggestParameters()
+ {
+ Query = "123 East",
+ At = new Coordinate()
+ {
+ Latitude = 54.2,
+ Longitude = 45.2,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildAutosuggestRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the building of the browse parameters is done successfully.
///
@@ -1038,6 +1128,29 @@ public void BuildBrowseRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildBrowseRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new BrowseParameters()
+ {
+ At = new Coordinate()
+ {
+ Latitude = 54.2,
+ Longitude = 45.2,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildBrowseRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the building of the lookup parameters is done successfully.
///
@@ -1089,6 +1202,25 @@ public void BuildLookupRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildLookupRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new LookupParameters()
+ {
+ Id = "12345sudfinm",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildLookupRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the validation and creation of the lookup uri is done successfully.
///
diff --git a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
index ae63b25..fa41427 100644
--- a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
+++ b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs
@@ -280,6 +280,25 @@ public void BuildGeocodingRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters()
+ {
+ Query = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the building of the reverse geocoding parameters is done successfully.
///
@@ -357,6 +376,29 @@ public void BuildReverseGeocodingRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodingParameters()
+ {
+ Coordinate = new Coordinate()
+ {
+ Latitude = 56.78,
+ Longitude = 78.91,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildReverseGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the validation and creation of the reverse geocoding uri is done successfully.
///
@@ -561,4 +603,4 @@ private MapBoxGeocoding BuildService()
return new MapBoxGeocoding(_httpClient, _options.Object);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs b/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs
index 05db971..04e20c2 100644
--- a/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs
+++ b/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs
@@ -288,6 +288,25 @@ public void BuildGeocodingRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters()
+ {
+ Location = "1 Microsoft Way Redmond WA",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the building of the licensed reverse geocoding parameters is done successfully.
///
@@ -401,6 +420,29 @@ public void BuildReverseGeocodingRequestFailsWithException()
#endif
}
+ [Fact]
+ public void BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodingParameters()
+ {
+ Location = new Coordinate()
+ {
+ Latitude = 56.78,
+ Longitude = 78.91,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildReverseGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
///
/// Tests the validation and creation of the reverse geocoding uri is done successfully.
///
@@ -566,4 +608,4 @@ private MapQuestGeocoding BuildService()
return new MapQuestGeocoding(_httpClient, _options.Object);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Geo.Positionstack.Tests/Services/PositionstackGeocodingShould.cs b/test/Geo.Positionstack.Tests/Services/PositionstackGeocodingShould.cs
index 87c8f00..4ffe847 100644
--- a/test/Geo.Positionstack.Tests/Services/PositionstackGeocodingShould.cs
+++ b/test/Geo.Positionstack.Tests/Services/PositionstackGeocodingShould.cs
@@ -222,6 +222,25 @@ public void BuildGeocodingRequest_WithInvalidParameters_FailsWithException()
#endif
}
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters()
+ {
+ Query = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
[Theory]
[ClassData(typeof(CultureTestData))]
public void BuildReverseGeocodingRequest_WithValidParameters_SuccessfullyBuildsUrl(CultureInfo culture)
@@ -269,6 +288,29 @@ public void BuildReverseGeocodingRequest_WithInvalidParameters_FailsWithExceptio
#endif
}
+ [Fact]
+ public void BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodingParameters()
+ {
+ Coordinate = new Coordinate()
+ {
+ Latitude = 56.78,
+ Longitude = 78.91,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildReverseGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
[Fact]
public void ValidateAndBuildUri_WithValidParameters_SuccessfullyBuildsUri()
{
@@ -345,4 +387,4 @@ private PositionstackGeocoding BuildService()
return new PositionstackGeocoding(_httpClient, _options.Object);
}
}
-}
\ No newline at end of file
+}
diff --git a/test/Geo.Radar.Tests/Services/RadarGeocodingShould.cs b/test/Geo.Radar.Tests/Services/RadarGeocodingShould.cs
index a288754..136c932 100644
--- a/test/Geo.Radar.Tests/Services/RadarGeocodingShould.cs
+++ b/test/Geo.Radar.Tests/Services/RadarGeocodingShould.cs
@@ -216,6 +216,25 @@ public void BuildGeocodingRequest_WithCharacterNeedingEncoding_SuccessfullyBuild
uri.PathAndQuery.Should().Contain("query=123%20East%20%23425");
}
+ [Fact]
+ public void BuildGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new GeocodingParameters()
+ {
+ Query = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
[Fact]
public void BuildGeocodingRequest_WithInvalidParameters_FailsWithException()
{
@@ -284,6 +303,29 @@ public void BuildReverseGeocodingRequest_WithInvalidParameters_FailsWithExceptio
#endif
}
+ [Fact]
+ public void BuildReverseGeocodingRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new ReverseGeocodingParameters()
+ {
+ Coordinate = new Coordinate()
+ {
+ Latitude = 56.78,
+ Longitude = 78.91,
+ },
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildReverseGeocodingRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
[Theory]
[ClassData(typeof(CultureTestData))]
public void BuildAutocompleteRequest_WithValidParameters_SuccessfullyBuildsUrl(CultureInfo culture)
@@ -345,6 +387,25 @@ public void BuildAutocompleteRequest_WithInvalidParameters_FailsWithException()
#endif
}
+ [Fact]
+ public void BuildAutocompleteRequest_WithAdditionalParameters_AddsThemToQueryString()
+ {
+ var sut = BuildService();
+
+ var parameters = new AutocompleteParameters()
+ {
+ Query = "123 East",
+ };
+
+ parameters.AdditionalParameters.Add("customKey1", "customValue1");
+ parameters.AdditionalParameters.Add("customKey2", "customValue2");
+
+ var uri = sut.BuildAutocompleteRequest(parameters);
+ var query = HttpUtility.UrlDecode(uri.PathAndQuery);
+ query.Should().Contain("customKey1=customValue1");
+ query.Should().Contain("customKey2=customValue2");
+ }
+
[Fact]
public void ValidateAndBuildUri_WithValidParameters_SuccessfullyBuildsUri()
{
@@ -477,4 +538,4 @@ private RadarGeocoding BuildService()
return new RadarGeocoding(_httpClient, _options.Object);
}
}
-}
\ No newline at end of file
+}