1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-09 00:46:19 +00:00

Added array serialization option, adjusted array converter

This commit is contained in:
Jan Korf 2019-08-29 09:30:17 +02:00
parent c75636a017
commit 88b02b0b41
7 changed files with 86 additions and 7 deletions

View File

@ -0,0 +1,11 @@
using System;
namespace CryptoExchange.Net.Attributes
{
/// <summary>
/// Used for conversion in ArrayConverter
/// </summary>
public class JsonConversionAttribute: Attribute
{
}
}

View File

@ -3,6 +3,7 @@ using System.Collections;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using CryptoExchange.Net.Attributes;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -74,7 +75,20 @@ namespace CryptoExchange.Net.Converters
} }
var converterAttribute = (JsonConverterAttribute)property.GetCustomAttribute(typeof(JsonConverterAttribute)) ?? (JsonConverterAttribute)property.PropertyType.GetCustomAttribute(typeof(JsonConverterAttribute)); var converterAttribute = (JsonConverterAttribute)property.GetCustomAttribute(typeof(JsonConverterAttribute)) ?? (JsonConverterAttribute)property.PropertyType.GetCustomAttribute(typeof(JsonConverterAttribute));
var value = converterAttribute != null ? arr[attribute.Index].ToObject(property.PropertyType, new JsonSerializer { Converters = { (JsonConverter)Activator.CreateInstance(converterAttribute.ConverterType) } }) : arr[attribute.Index]; var conversionAttribute = (JsonConversionAttribute)property.GetCustomAttribute(typeof(JsonConversionAttribute)) ?? (JsonConversionAttribute)property.PropertyType.GetCustomAttribute(typeof(JsonConversionAttribute));
object value = null;
if (converterAttribute != null)
{
value = arr[attribute.Index].ToObject(property.PropertyType, new JsonSerializer {Converters = {(JsonConverter) Activator.CreateInstance(converterAttribute.ConverterType)}});
}
else if (conversionAttribute != null)
{
value = arr[attribute.Index].ToObject(property.PropertyType);
}
else
{
value = arr[attribute.Index];
}
if (value != null && property.PropertyType.IsInstanceOfType(value)) if (value != null && property.PropertyType.IsInstanceOfType(value))
property.SetValue(result, value); property.SetValue(result, value);

View File

@ -4,6 +4,11 @@
<name>CryptoExchange.Net</name> <name>CryptoExchange.Net</name>
</assembly> </assembly>
<members> <members>
<member name="T:CryptoExchange.Net.Attributes.JsonConversionAttribute">
<summary>
Used for conversion in ArrayConverter
</summary>
</member>
<member name="T:CryptoExchange.Net.Attributes.JsonOptionalPropertyAttribute"> <member name="T:CryptoExchange.Net.Attributes.JsonOptionalPropertyAttribute">
<summary> <summary>
Marks property as optional Marks property as optional
@ -446,12 +451,13 @@
<param name="key"></param> <param name="key"></param>
<param name="value"></param> <param name="value"></param>
</member> </member>
<member name="M:CryptoExchange.Net.ExtensionMethods.CreateParamString(System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean)"> <member name="M:CryptoExchange.Net.ExtensionMethods.CreateParamString(System.Collections.Generic.Dictionary{System.String,System.Object},System.Boolean,CryptoExchange.Net.Objects.ArrayParametersSerialization)">
<summary> <summary>
Create a query string of the specified parameters Create a query string of the specified parameters
</summary> </summary>
<param name="parameters">The parameters to use</param> <param name="parameters">The parameters to use</param>
<param name="urlEncodeValues">Whether or not the values should be url encoded</param> <param name="urlEncodeValues">Whether or not the values should be url encoded</param>
<param name="serializationType">How to serialize array parameters</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:CryptoExchange.Net.ExtensionMethods.GetString(System.Security.SecureString)"> <member name="M:CryptoExchange.Net.ExtensionMethods.GetString(System.Security.SecureString)">
@ -1182,6 +1188,21 @@
Bid Bid
</summary> </summary>
</member> </member>
<member name="T:CryptoExchange.Net.Objects.ArrayParametersSerialization">
<summary>
Define how array parameters should be send
</summary>
</member>
<member name="F:CryptoExchange.Net.Objects.ArrayParametersSerialization.MultipleValues">
<summary>
Send multiple key=value for each entry
</summary>
</member>
<member name="F:CryptoExchange.Net.Objects.ArrayParametersSerialization.Array">
<summary>
Create an []=value array
</summary>
</member>
<member name="T:CryptoExchange.Net.Objects.Error"> <member name="T:CryptoExchange.Net.Objects.Error">
<summary> <summary>
Base class for errors Base class for errors
@ -1846,6 +1867,11 @@
Request body content type Request body content type
</summary> </summary>
</member> </member>
<member name="F:CryptoExchange.Net.RestClient.arraySerialization">
<summary>
How to serialize array parameters
</summary>
</member>
<member name="P:CryptoExchange.Net.RestClient.RequestTimeout"> <member name="P:CryptoExchange.Net.RestClient.RequestTimeout">
<summary> <summary>
Timeout for requests Timeout for requests

View File

@ -8,6 +8,7 @@ using System.Security;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using CryptoExchange.Net.Logging; using CryptoExchange.Net.Logging;
using CryptoExchange.Net.Objects;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
@ -69,14 +70,22 @@ namespace CryptoExchange.Net
/// </summary> /// </summary>
/// <param name="parameters">The parameters to use</param> /// <param name="parameters">The parameters to use</param>
/// <param name="urlEncodeValues">Whether or not the values should be url encoded</param> /// <param name="urlEncodeValues">Whether or not the values should be url encoded</param>
/// <param name="serializationType">How to serialize array parameters</param>
/// <returns></returns> /// <returns></returns>
public static string CreateParamString(this Dictionary<string, object> parameters, bool urlEncodeValues) public static string CreateParamString(this Dictionary<string, object> parameters, bool urlEncodeValues, ArrayParametersSerialization serializationType)
{ {
var uriString = ""; var uriString = "";
var arraysParameters = parameters.Where(p => p.Value.GetType().IsArray).ToList(); var arraysParameters = parameters.Where(p => p.Value.GetType().IsArray).ToList();
foreach (var arrayEntry in arraysParameters) foreach (var arrayEntry in arraysParameters)
{ {
if(serializationType == ArrayParametersSerialization.Array)
uriString += $"{string.Join("&", ((object[])(urlEncodeValues ? WebUtility.UrlEncode(arrayEntry.Value.ToString()) : arrayEntry.Value)).Select(v => $"{arrayEntry.Key}[]={v}"))}&"; uriString += $"{string.Join("&", ((object[])(urlEncodeValues ? WebUtility.UrlEncode(arrayEntry.Value.ToString()) : arrayEntry.Value)).Select(v => $"{arrayEntry.Key}[]={v}"))}&";
else
{
var array = (Array)arrayEntry.Value;
uriString += string.Join("&", array.OfType<object>().Select(a => $"{arrayEntry.Key}={WebUtility.UrlEncode(a.ToString())}"));
uriString += "&";
}
} }
uriString += $"{string.Join("&", parameters.Where(p => !p.Value.GetType().IsArray).Select(s => $"{s.Key}={(urlEncodeValues ? WebUtility.UrlEncode(s.Value.ToString()) : s.Value)}"))}"; uriString += $"{string.Join("&", parameters.Where(p => !p.Value.GetType().IsArray).Select(s => $"{s.Key}={(urlEncodeValues ? WebUtility.UrlEncode(s.Value.ToString()) : s.Value)}"))}";

View File

@ -82,4 +82,19 @@
/// </summary> /// </summary>
Bid Bid
} }
/// <summary>
/// Define how array parameters should be send
/// </summary>
public enum ArrayParametersSerialization
{
/// <summary>
/// Send multiple key=value for each entry
/// </summary>
MultipleValues,
/// <summary>
/// Create an []=value array
/// </summary>
Array
}
} }

View File

@ -39,6 +39,11 @@ namespace CryptoExchange.Net
/// </summary> /// </summary>
protected RequestBodyFormat requestBodyFormat = RequestBodyFormat.Json; protected RequestBodyFormat requestBodyFormat = RequestBodyFormat.Json;
/// <summary>
/// How to serialize array parameters
/// </summary>
protected ArrayParametersSerialization arraySerialization = ArrayParametersSerialization.Array;
/// <summary> /// <summary>
/// Timeout for requests /// Timeout for requests
/// </summary> /// </summary>
@ -222,7 +227,7 @@ namespace CryptoExchange.Net
parameters = authProvider.AddAuthenticationToParameters(uriString, method, parameters, signed); parameters = authProvider.AddAuthenticationToParameters(uriString, method, parameters, signed);
if((method == Constants.GetMethod || method == Constants.DeleteMethod || postParametersPosition == PostParameters.InUri) && parameters?.Any() == true) if((method == Constants.GetMethod || method == Constants.DeleteMethod || postParametersPosition == PostParameters.InUri) && parameters?.Any() == true)
uriString += "?" + parameters.CreateParamString(true); uriString += "?" + parameters.CreateParamString(true, arraySerialization);
var request = RequestFactory.Create(uriString); var request = RequestFactory.Create(uriString);
request.ContentType = requestBodyFormat == RequestBodyFormat.Json ? Constants.JsonContentHeader : Constants.FormContentHeader; request.ContentType = requestBodyFormat == RequestBodyFormat.Json ? Constants.JsonContentHeader : Constants.FormContentHeader;

View File

@ -175,7 +175,6 @@ namespace CryptoExchange.Net
await socket.Close(handler).ConfigureAwait(false); await socket.Close(handler).ConfigureAwait(false);
return new CallResult<UpdateSubscription>(null, subResult.Error); return new CallResult<UpdateSubscription>(null, subResult.Error);
} }
} }
else else
handler.Confirmed = true; handler.Confirmed = true;
@ -554,7 +553,7 @@ namespace CryptoExchange.Net
/// <returns></returns> /// <returns></returns>
public virtual async Task UnsubscribeAll() public virtual async Task UnsubscribeAll()
{ {
log.Write(LogVerbosity.Debug, $"Closing all {sockets.Count} subscriptions"); log.Write(LogVerbosity.Debug, $"Closing all {sockets.Sum(s => s.Value.handlers.Count(h => h.UserSubscription))} subscriptions");
await Task.Run(() => await Task.Run(() =>
{ {