我正在创建一个端点来从加密货币市场获取特定加密货币的价格。 我正在使用 Kucoin 和 Binance 的 API。当我收到回复时,两个回复中都有
bids
和 asks
字段。两个 API 响应都有不同的结构,但是我只需要这个字段。如何创建通用模型并将 api 的响应反序列化到该模型中?
我当前的代码:
// OrderBookResponse
public class OrderBookResponse
{
public OrderBookData Data { get; set; }
}
// OrderBookData
public class OrderBookData
{
public List<List<string>> Bids { get; set; }
public List<List<string>> Asks { get; set; }
}
库币服务
public ExchangeRate GetExchangeRateAsync(GetRatesModel getRates)
{
var uriBuilder = new UriBuilder(CryptoExchangeUrls.KucoinApi)
{
Path = "/api/v1/market/orderbook/level2_20",
Query = $"symbol={getRates.BaseCurrency.ToUpper()}-{getRates.QuoteCurrency.ToUpper()}"
};
using var client = new HttpClient();
HttpResponseMessage response = client.GetAsync(uriBuilder.Uri).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception($"HTTP request failed with status code {response.StatusCode}");
}
OrderBookResponse deserializedResponse = response.Content.ReadFromJsonAsync<OrderBookResponse>().Result;
ExchangeRate exchangeRate = new ExchangeRate()
{
ExchangeName = "Kucoin",
Rate = PriceHelper.GetAveragePrice(deserializedResponse.Data)
};
return exchangeRate;
}
币安服务
public ExchangeRate GetExchangeRateAsync(GetRatesModel getRates)
{
var uriBuilder = new UriBuilder($"{CryptoExchangeUrls.BinanceApi}/api/v3/depth")
{
Query = $"limit=10&symbol={getRates.BaseCurrency.ToUpper()}{getRates.QuoteCurrency.ToUpper()}"
};
using var client = new HttpClient();
HttpResponseMessage response = client.GetAsync(uriBuilder.Uri).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception($"HTTP request failed with status code {response.StatusCode}");
}
OrderBookResponse deserializedResponse = response.Content.ReadFromJsonAsync<OrderBookResponse>().Result;
ExchangeRate exchangeRate = new ExchangeRate()
{
ExchangeName = "Binance",
Rate = PriceHelper.GetAveragePrice(deserializedResponse.Data)
};
return exchangeRate;
}
我正在使用这个端点:
https://api.kucoin.com/api/v1/market/orderbook/level2_20?symbol=BTC-USDT
https://api.binance.com/api/v3/depth?limit=10&symbol=BTCUSDT
您可以使用模板函数来尝试将响应字符串反序列化为对象。有了这样的模型:
public class GenericApiResponse
{
public HttpStatusCode StatusCode { get; set; }
public string Content { get; set; }
}
您可以使用非常通用的功能,例如
public async Task<GenericApiResponse> ExecuteRequest(MethodEnum method, string resource, AuthModel authType,
object body = null, Dictionary<string, string> queryParams = null, Dictionary<string, string> headers = null)
{
Method requestMethod = MethodEnumExtensions.ToHttpMethod(method);
var request = new RestRequest(resource, requestMethod);
if (authType.Authenticate)
{
request.AddHeader("Authorization", $"{authType.TokenType} {_authToken}");
}
if (body != null)
{
request.AddJsonBody(body);
}
if (queryParams != null)
{
foreach (var param in queryParams)
{
request.AddQueryParameter(param.Key, param.Value);
}
}
if (headers != null)
{
foreach (var header in headers)
{
request.AddHeader(header.Key, header.Value);
}
}
var response = await _client.ExecuteAsync(request);
if (!response.IsSuccessStatusCode)
{
_logger.LogError($"Received error status code for request {resource}, code: {response.StatusCode}, message: {response.Content ?? "NO MESSAGE"}");
}
return new GenericApiResponse
{
Content = response.Content,
StatusCode = response.StatusCode
};
}
然后使该函数适用于任何对象
public async Task<TResponse> ExecuteRequest<TResponse>(MethodEnum method, string resource, AuthModel authType,
object body = null, Dictionary<string, string> queryParams = null, Dictionary<string, string> headers = null)
{
var response = await ExecuteRequest(method, resource, authType, body, queryParams, headers);
if (response == null || response.Content == null)
{
_logger.LogError("Received null response");
return default(TResponse);
}
TResponse result;
try
{
result = JsonConvert.DeserializeObject<TResponse>(response.Content);
}
catch (Exception ex)
{
result = JsonConvert.DeserializeObject<TResponse>(JsonConvert.SerializeObject(response.Content));
}
return result;
}