mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-27 01:36:10 +00:00
* Added support for Native AOT compilation * Updated all IEnumerable response types to array response types * Added Pass support for ApiCredentials, removing the need for most implementations to add their own ApiCredentials type * Added KeepAliveTimeout setting setting ping frame timeouts for SocketApiClient * Added IBookTickerRestClient Shared interface for requesting book tickers * Added ISpotTriggerOrderRestClient Shared interface for managing spot trigger orders * Added ISpotOrderClientIdClient Shared interface for managing spot orders by client order id * Added IFuturesTriggerOrderRestClient Shared interface for managing futures trigger orders * Added IFuturesOrderClientIdClient Shared interface for managing futures orders by client order id * Added IFuturesTpSlRestClient Shared interface for setting TP/SL on open futures positions * Added GenerateClientOrderId to ISpotOrderRestClient and IFuturesOrderRestClient interface * Added OptionalExchangeParameters and Supported properties to EndpointOptions * Refactor Shared interfaces quantity parameters and properties to use SharedQuantity * Added SharedSymbol property to Shared interface models returning a symbol * Added TriggerPrice, IsTriggerOrder, TakeProfitPrice, StopLossPrice and IsCloseOrder to SharedFuturesOrder response model * Added MaxShortLeverage and MaxLongLeverage to SharedFuturesSymbol response model * Added StopLossPrice and TakeProfitPrice to SharedPosition response model * Added TriggerPrice and IsTriggerOrder to SharedSpotOrder response model * Added QuoteVolume property to SharedSpotTicker response model * Added AssetAlias configuration models * Added static ExchangeSymbolCache for tracking symbol information from exchanges * Added static CallResult.SuccessResult to be used instead of constructing success CallResult instance * Added static ApplyRules, RandomHexString and RandomLong helper methods to ExchangeHelpers class * Added AsErrorWithData To CallResult * Added OriginalData property to CallResult * Added support for adjusting the rate limit key per call, allowing for ratelimiting depending on request parameters * Added implementation for integration testing ISymbolOrderBook instances * Added implementation for integration testing socket subscriptions * Added implementation for testing socket queries * Updated request cancellation logging to Debug level * Updated logging SourceContext to include the client type * Updated some logging logic, errors no longer contain any data, exception are not logged as string but instead forwarded to structured logging * Fixed warning for Enum parsing throwing exception and output warnings for each object in a response to only once to prevent slowing down execution * Fixed memory leak in AsyncAutoRestEvent * Fixed logging for ping frame timeout * Fixed warning getting logged when user stops SymbolOrderBook instance * Fixed socket client `UnsubscribeAll` not unsubscribing dedicated connections * Fixed memory leak in Rest client cache * Fixed integers bigger than int16 not getting correctly parsed to enums * Fixed issue where the default options were overridden when using SetApiCredentials * Removed Newtonsoft.Json dependency * Removed legacy Rest client code * Removed legacy ISpotClient and IFuturesClient support
589 lines
21 KiB
C#
589 lines
21 KiB
C#
using CryptoExchange.Net.SharedApis;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
|
|
namespace CryptoExchange.Net.Objects
|
|
{
|
|
/// <summary>
|
|
/// The result of an operation
|
|
/// </summary>
|
|
public class CallResult
|
|
{
|
|
/// <summary>
|
|
/// Static success result
|
|
/// </summary>
|
|
public static CallResult SuccessResult { get; } = new CallResult(null);
|
|
|
|
/// <summary>
|
|
/// An error if the call didn't succeed, will always be filled if Success = false
|
|
/// </summary>
|
|
public Error? Error { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// Whether the call was successful
|
|
/// </summary>
|
|
public bool Success => Error == null;
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
/// <param name="error"></param>
|
|
public CallResult(Error? error)
|
|
{
|
|
Error = error;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Overwrite bool check so we can use if(callResult) instead of if(callResult.Success)
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
public static implicit operator bool(CallResult obj)
|
|
{
|
|
return obj?.Success == true;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
return Success ? $"Success" : $"Error: {Error}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The result of an operation
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class CallResult<T>: CallResult
|
|
{
|
|
/// <summary>
|
|
/// The data returned by the call, only available when Success = true
|
|
/// </summary>
|
|
public T Data { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// The original data returned by the call, only available when `OutputOriginalData` is set to `true` in the client options
|
|
/// </summary>
|
|
public string? OriginalData { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
/// <param name="data"></param>
|
|
/// <param name="originalData"></param>
|
|
/// <param name="error"></param>
|
|
#pragma warning disable 8618
|
|
public CallResult([AllowNull]T data, string? originalData, Error? error): base(error)
|
|
#pragma warning restore 8618
|
|
{
|
|
OriginalData = originalData;
|
|
#pragma warning disable 8601
|
|
Data = data;
|
|
#pragma warning restore 8601
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a new data result
|
|
/// </summary>
|
|
/// <param name="data">The data to return</param>
|
|
public CallResult(T data) : this(data, null, null) { }
|
|
|
|
/// <summary>
|
|
/// Create a new error result
|
|
/// </summary>
|
|
/// <param name="error">The error to return</param>
|
|
public CallResult(Error error) : this(default, null, error) { }
|
|
|
|
/// <summary>
|
|
/// Create a new error result
|
|
/// </summary>
|
|
/// <param name="error">The error to return</param>
|
|
/// <param name="originalData">The original response data</param>
|
|
public CallResult(Error error, string? originalData) : this(default, originalData, error) { }
|
|
|
|
/// <summary>
|
|
/// Overwrite bool check so we can use if(callResult) instead of if(callResult.Success)
|
|
/// </summary>
|
|
/// <param name="obj"></param>
|
|
public static implicit operator bool(CallResult<T> obj)
|
|
{
|
|
return obj?.Success == true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Whether the call was successful or not. Useful for nullability checking.
|
|
/// </summary>
|
|
/// <param name="data">The data returned by the call.</param>
|
|
/// <param name="error"><see cref="Error"/> on failure.</param>
|
|
/// <returns><c>true</c> when <see cref="CallResult{T}"/> succeeded, <c>false</c> otherwise.</returns>
|
|
public bool GetResultOrError([MaybeNullWhen(false)] out T data, [NotNullWhen(false)] out Error? error)
|
|
{
|
|
if (Success)
|
|
{
|
|
data = Data!;
|
|
error = null;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
data = default;
|
|
error = Error!;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="data">The data of the new type</param>
|
|
/// <returns></returns>
|
|
public CallResult<K> As<K>([AllowNull] K data)
|
|
{
|
|
return new CallResult<K>(data, OriginalData, Error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy as a dataless result
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public CallResult AsDataless()
|
|
{
|
|
return SuccessResult;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy as a dataless result
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public CallResult AsDatalessError(Error error)
|
|
{
|
|
return new CallResult(error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the CallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="data">The data</param>
|
|
/// <param name="error">The error returned</param>
|
|
/// <returns></returns>
|
|
public CallResult<K> AsErrorWithData<K>(Error error, K data)
|
|
{
|
|
return new CallResult<K>(data, OriginalData, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="error">The error to return</param>
|
|
/// <returns></returns>
|
|
public CallResult<K> AsError<K>(Error error)
|
|
{
|
|
return new CallResult<K>(default, OriginalData, error);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
return Success ? $"Success" : $"Error: {Error}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The result of a request
|
|
/// </summary>
|
|
public class WebCallResult : CallResult
|
|
{
|
|
/// <summary>
|
|
/// The request http method
|
|
/// </summary>
|
|
public HttpMethod? RequestMethod { get; set; }
|
|
|
|
/// <summary>
|
|
/// The headers sent with the request
|
|
/// </summary>
|
|
public KeyValuePair<string, string[]>[]? RequestHeaders { get; set; }
|
|
|
|
/// <summary>
|
|
/// The request id
|
|
/// </summary>
|
|
public int? RequestId { get; set; }
|
|
|
|
/// <summary>
|
|
/// The url which was requested
|
|
/// </summary>
|
|
public string? RequestUrl { get; set; }
|
|
|
|
/// <summary>
|
|
/// The body of the request
|
|
/// </summary>
|
|
public string? RequestBody { get; set; }
|
|
|
|
/// <summary>
|
|
/// The original data returned by the call, only available when `OutputOriginalData` is set to `true` in the client options
|
|
/// </summary>
|
|
public string? OriginalData { get; internal set; }
|
|
|
|
/// <summary>
|
|
/// The status code of the response. Note that a OK status does not always indicate success, check the Success parameter for this.
|
|
/// </summary>
|
|
public HttpStatusCode? ResponseStatusCode { get; set; }
|
|
|
|
/// <summary>
|
|
/// The response headers
|
|
/// </summary>
|
|
public KeyValuePair<string, string[]>[]? ResponseHeaders { get; set; }
|
|
|
|
/// <summary>
|
|
/// The time between sending the request and receiving the response
|
|
/// </summary>
|
|
public TimeSpan? ResponseTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
public WebCallResult(
|
|
HttpStatusCode? code,
|
|
KeyValuePair<string, string[]>[]? responseHeaders,
|
|
TimeSpan? responseTime,
|
|
string? originalData,
|
|
int? requestId,
|
|
string? requestUrl,
|
|
string? requestBody,
|
|
HttpMethod? requestMethod,
|
|
KeyValuePair<string, string[]>[]? requestHeaders,
|
|
Error? error) : base(error)
|
|
{
|
|
ResponseStatusCode = code;
|
|
ResponseHeaders = responseHeaders;
|
|
ResponseTime = responseTime;
|
|
RequestId = requestId;
|
|
OriginalData = originalData;
|
|
|
|
RequestUrl = requestUrl;
|
|
RequestBody = requestBody;
|
|
RequestHeaders = requestHeaders;
|
|
RequestMethod = requestMethod;
|
|
}
|
|
|
|
/// <summary>
|
|
/// ctor
|
|
/// </summary>
|
|
/// <param name="error"></param>
|
|
public WebCallResult(Error error): base(error) { }
|
|
|
|
/// <summary>
|
|
/// Return the result as an error result
|
|
/// </summary>
|
|
/// <param name="error">The error returned</param>
|
|
/// <returns></returns>
|
|
public WebCallResult AsError(Error error)
|
|
{
|
|
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="data">The data of the new type</param>
|
|
/// <returns></returns>
|
|
public WebCallResult<K> As<K>([AllowNull] K data)
|
|
{
|
|
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, 0, null, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, ResultDataSource.Server, data, Error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="tradeMode">Trade mode the result applies to</param>
|
|
/// <param name="data">The data</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode tradeMode, [AllowNull] K data)
|
|
{
|
|
return new ExchangeWebResult<K>(exchange, tradeMode, this.As<K>(data));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="tradeModes">Trade modes the result applies to</param>
|
|
/// <param name="data">The data</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode[]? tradeModes, [AllowNull] K data)
|
|
{
|
|
return new ExchangeWebResult<K>(exchange, tradeModes, this.As<K>(data));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="error">The error returned</param>
|
|
/// <returns></returns>
|
|
public WebCallResult<K> AsError<K>(Error error)
|
|
{
|
|
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, 0, null, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, ResultDataSource.Server, default, error);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
return (Success ? $"Success" : $"Error: {Error}") + $" in {ResponseTime}";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The result of a request
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class WebCallResult<T>: CallResult<T>
|
|
{
|
|
/// <summary>
|
|
/// The request http method
|
|
/// </summary>
|
|
public HttpMethod? RequestMethod { get; set; }
|
|
|
|
/// <summary>
|
|
/// The headers sent with the request
|
|
/// </summary>
|
|
public KeyValuePair<string, string[]>[]? RequestHeaders { get; set; }
|
|
|
|
/// <summary>
|
|
/// The request id
|
|
/// </summary>
|
|
public int? RequestId { get; set; }
|
|
|
|
/// <summary>
|
|
/// The url which was requested
|
|
/// </summary>
|
|
public string? RequestUrl { get; set; }
|
|
|
|
/// <summary>
|
|
/// The body of the request
|
|
/// </summary>
|
|
public string? RequestBody { get; set; }
|
|
|
|
/// <summary>
|
|
/// The status code of the response. Note that a OK status does not always indicate success, check the Success parameter for this.
|
|
/// </summary>
|
|
public HttpStatusCode? ResponseStatusCode { get; set; }
|
|
|
|
/// <summary>
|
|
/// Length in bytes of the response
|
|
/// </summary>
|
|
public long? ResponseLength { get; set; }
|
|
|
|
/// <summary>
|
|
/// The response headers
|
|
/// </summary>
|
|
public KeyValuePair<string, string[]>[]? ResponseHeaders { get; set; }
|
|
|
|
/// <summary>
|
|
/// The time between sending the request and receiving the response
|
|
/// </summary>
|
|
public TimeSpan? ResponseTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// The data source of this result
|
|
/// </summary>
|
|
public ResultDataSource DataSource { get; set; } = ResultDataSource.Server;
|
|
|
|
/// <summary>
|
|
/// Create a new result
|
|
/// </summary>
|
|
/// <param name="code"></param>
|
|
/// <param name="responseHeaders"></param>
|
|
/// <param name="responseTime"></param>
|
|
/// <param name="responseLength"></param>
|
|
/// <param name="originalData"></param>
|
|
/// <param name="requestId"></param>
|
|
/// <param name="requestUrl"></param>
|
|
/// <param name="requestBody"></param>
|
|
/// <param name="requestMethod"></param>
|
|
/// <param name="requestHeaders"></param>
|
|
/// <param name="dataSource"></param>
|
|
/// <param name="data"></param>
|
|
/// <param name="error"></param>
|
|
public WebCallResult(
|
|
HttpStatusCode? code,
|
|
KeyValuePair<string, string[]>[]? responseHeaders,
|
|
TimeSpan? responseTime,
|
|
long? responseLength,
|
|
string? originalData,
|
|
int? requestId,
|
|
string? requestUrl,
|
|
string? requestBody,
|
|
HttpMethod? requestMethod,
|
|
KeyValuePair<string, string[]>[]? requestHeaders,
|
|
ResultDataSource dataSource,
|
|
[AllowNull] T data,
|
|
Error? error) : base(data, originalData, error)
|
|
{
|
|
ResponseStatusCode = code;
|
|
ResponseHeaders = responseHeaders;
|
|
ResponseTime = responseTime;
|
|
ResponseLength = responseLength;
|
|
|
|
RequestId = requestId;
|
|
RequestUrl = requestUrl;
|
|
RequestBody = requestBody;
|
|
RequestHeaders = requestHeaders;
|
|
RequestMethod = requestMethod;
|
|
DataSource = dataSource;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy as a dataless result
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public new WebCallResult AsDataless()
|
|
{
|
|
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, Error);
|
|
}
|
|
/// <summary>
|
|
/// Copy as a dataless result
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public new WebCallResult AsDatalessError(Error error)
|
|
{
|
|
return new WebCallResult(ResponseStatusCode, ResponseHeaders, ResponseTime, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create a new error result
|
|
/// </summary>
|
|
/// <param name="error">The error</param>
|
|
public WebCallResult(Error? error) : this(null, null, null, null, null, null, null, null, null, null, ResultDataSource.Server, default, error) { }
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="data">The data of the new type</param>
|
|
/// <returns></returns>
|
|
public new WebCallResult<K> As<K>([AllowNull] K data)
|
|
{
|
|
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, Error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="error">The error returned</param>
|
|
/// <returns></returns>
|
|
public new WebCallResult<K> AsError<K>(Error error)
|
|
{
|
|
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, default, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="data">The data</param>
|
|
/// <param name="error">The error returned</param>
|
|
/// <returns></returns>
|
|
public new WebCallResult<K> AsErrorWithData<K>(Error error, K data)
|
|
{
|
|
return new WebCallResult<K>(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, DataSource, data, error);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
|
/// </summary>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="tradeMode">Trade mode the result applies to</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<T> AsExchangeResult(string exchange, TradingMode tradeMode)
|
|
{
|
|
return new ExchangeWebResult<T>(exchange, tradeMode, this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
|
/// </summary>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="tradeModes">Trade modes the result applies to</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<T> AsExchangeResult(string exchange, TradingMode[] tradeModes)
|
|
{
|
|
return new ExchangeWebResult<T>(exchange, tradeModes, this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="tradeMode">Trade mode the result applies to</param>
|
|
/// <param name="data">Data</param>
|
|
/// <param name="nextPageToken">Next page token</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode tradeMode, [AllowNull] K data, INextPageToken? nextPageToken = null)
|
|
{
|
|
return new ExchangeWebResult<K>(exchange, tradeMode, As<K>(data), nextPageToken);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult of a new data type
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="tradeModes">Trade modes the result applies to</param>
|
|
/// <param name="data">Data</param>
|
|
/// <param name="nextPageToken">Next page token</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<K> AsExchangeResult<K>(string exchange, TradingMode[]? tradeModes, [AllowNull] K data, INextPageToken? nextPageToken = null)
|
|
{
|
|
return new ExchangeWebResult<K>(exchange, tradeModes, As<K>(data), nextPageToken);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copy the WebCallResult to an ExchangeWebResult with a specific error
|
|
/// </summary>
|
|
/// <typeparam name="K">The new type</typeparam>
|
|
/// <param name="exchange">The exchange</param>
|
|
/// <param name="error">The error returned</param>
|
|
/// <returns></returns>
|
|
public ExchangeWebResult<K> AsExchangeError<K>(string exchange, Error error)
|
|
{
|
|
return new ExchangeWebResult<K>(exchange, null, AsError<K>(error));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return a copy of this result with data source set to cache
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
internal WebCallResult<T> Cached()
|
|
{
|
|
return new WebCallResult<T>(ResponseStatusCode, ResponseHeaders, ResponseTime, ResponseLength, OriginalData, RequestId, RequestUrl, RequestBody, RequestMethod, RequestHeaders, ResultDataSource.Cache, Data, Error);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
var sb = new StringBuilder();
|
|
sb.Append(Success ? $"Success response" : $"Error response: {Error}");
|
|
if (ResponseLength != null)
|
|
sb.Append($", {ResponseLength} bytes");
|
|
if (ResponseTime != null)
|
|
sb.Append($", received in {Math.Round(ResponseTime?.TotalMilliseconds ?? 0)}ms");
|
|
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
}
|