diff --git a/CryptoExchange.Net/Converters/SystemTextJson/CommaSplitStringConverter.cs b/CryptoExchange.Net/Converters/SystemTextJson/CommaSplitStringConverter.cs
new file mode 100644
index 0000000..b3ec015
--- /dev/null
+++ b/CryptoExchange.Net/Converters/SystemTextJson/CommaSplitStringConverter.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace CryptoExchange.Net.Converters.SystemTextJson
+{
+ ///
+ /// Converter for comma separated string values
+ ///
+ public class CommaSplitStringConverter : JsonConverter
+ {
+ ///
+ public override string[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ var str = reader.GetString();
+ if (string.IsNullOrEmpty(str))
+ return [];
+
+ return str!.Split(',').ToArray() ?? [];
+ }
+
+ ///
+ public override void Write(Utf8JsonWriter writer, string[] value, JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(string.Join(",", value));
+ }
+ }
+}
diff --git a/CryptoExchange.Net/ExtensionMethods.cs b/CryptoExchange.Net/ExtensionMethods.cs
index 6f78e63..7dd272c 100644
--- a/CryptoExchange.Net/ExtensionMethods.cs
+++ b/CryptoExchange.Net/ExtensionMethods.cs
@@ -74,8 +74,13 @@ namespace CryptoExchange.Net
{
if (serializationType == ArrayParametersSerialization.Array)
{
- foreach(var entry in (object[])parameter.Value)
+ bool firstArrayValue = true;
+ foreach (var entry in (object[])parameter.Value)
{
+ if (!firstArrayValue)
+ uriString.Append('&');
+ firstArrayValue = false;
+
uriString.Append(parameter.Key);
uriString.Append("[]=");
if (urlEncodeValues)
@@ -611,6 +616,26 @@ namespace CryptoExchange.Net
return services;
}
+
+ ///
+ /// Convert a hex encoded string to byte array
+ ///
+ ///
+ ///
+ public static byte[] HexStringToBytes(this string hexString)
+ {
+ if (hexString.StartsWith("0x"))
+ hexString = hexString.Substring(2);
+
+ byte[] bytes = new byte[hexString.Length / 2];
+ for (int i = 0; i < hexString.Length; i += 2)
+ {
+ string hexSubstring = hexString.Substring(i, 2);
+ bytes[i / 2] = Convert.ToByte(hexSubstring, 16);
+ }
+
+ return bytes;
+ }
}
}
diff --git a/CryptoExchange.Net/Objects/ParameterCollection.cs b/CryptoExchange.Net/Objects/ParameterCollection.cs
index daa011d..d49f8fa 100644
--- a/CryptoExchange.Net/Objects/ParameterCollection.cs
+++ b/CryptoExchange.Net/Objects/ParameterCollection.cs
@@ -96,6 +96,23 @@ namespace CryptoExchange.Net.Objects
base.Add(key, value.Value.ToString(CultureInfo.InvariantCulture));
}
+ ///
+ /// Add a DateTime value as string
+ ///
+ public void AddString(string key, DateTime value)
+ {
+ base.Add(key, value.ToString("yyyy-MM-ddTHH:mm:ssZ"));
+ }
+
+ ///
+ /// Add a DateTime value as string. Not added if value is null
+ ///
+ public void AddOptionalString(string key, DateTime? value)
+ {
+ if (value != null)
+ base.Add(key, value.Value.ToString("yyyy-MM-ddTHH:mm:ssZ"));
+ }
+
///
/// Add a datetime value as milliseconds timestamp
///
@@ -241,6 +258,45 @@ namespace CryptoExchange.Net.Objects
base.Add(key, int.Parse(stringVal));
}
}
+
+ ///
+ /// Add key as comma separated values
+ ///
+ public void AddCommaSeparated(string key, IEnumerable values)
+ {
+ base.Add(key, string.Join(",", values));
+ }
+
+ ///
+ /// Add key as comma separated values if there are values provided
+ ///
+ public void AddOptionalCommaSeparated(string key, IEnumerable? values)
+ {
+ if (values == null || !values.Any())
+ return;
+
+ base.Add(key, string.Join(",", values));
+ }
+
+ ///
+ /// Add key as boolean lower case value
+ ///
+ public void AddBoolString(string key, bool value)
+ {
+ base.Add(key, value.ToString().ToLower());
+ }
+
+ ///
+ /// Add key as boolean lower case value if it's not null
+ ///
+ public void AddOptionalBoolString(string key, bool? value)
+ {
+ if (value == null)
+ return;
+
+ base.Add(key, value.ToString()!.ToLower());
+ }
+
///
/// Set the request body. Can be used to specify a simple value or array as the body instead of an object