You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.9 KiB
118 lines
4.9 KiB
using Binance.TradeRobot.Common.Extensions;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
|
|
namespace Binance.TradeRobot.Common.Http
|
|
{
|
|
public class RestApiService
|
|
{
|
|
public const string ContentType_Json = "application/json";
|
|
public const string ContentType_Form = "application/x-www-form-urlencoded";
|
|
public TimeSpan TimeOut { get; set; } = new TimeSpan(0, 0, 20);
|
|
|
|
private IHttpClientFactory httpClientFactory;
|
|
|
|
public RestApiService(IHttpClientFactory httpClientFactory)
|
|
{
|
|
this.httpClientFactory = httpClientFactory;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送请求
|
|
/// </summary>
|
|
/// <param name="apiHost"></param>
|
|
/// <param name="apiPath"></param>
|
|
/// <param name="param"></param>
|
|
/// <param name="requestHeaders"></param>
|
|
/// <param name="httpMethod"></param>
|
|
/// <param name="contentType"></param>
|
|
/// <param name="paramPosition"></param>
|
|
/// <param name="useRandomTimeStamp"></param>
|
|
/// <param name="getResponseHeader"></param>
|
|
/// <param name="httpCompletionOption"></param>
|
|
/// <param name="httpClientName"></param>
|
|
/// <returns></returns>
|
|
public RestApiResult SendRequest(string apiHost,
|
|
string apiPath,
|
|
object param,
|
|
IDictionary<string, string> requestHeaders,
|
|
HttpMethod httpMethod,
|
|
string contentType = ContentType_Json,
|
|
ParamPosition paramPosition = ParamPosition.Body,
|
|
bool useRandomTimeStamp = false,
|
|
bool getResponseHeader = false,
|
|
HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead,
|
|
string httpClientName = "")
|
|
{
|
|
//Get和Delete强制使用QueryString形式传参
|
|
if (httpMethod == HttpMethod.Get || httpMethod == HttpMethod.Delete)
|
|
paramPosition = ParamPosition.Query;
|
|
|
|
//拼接Url
|
|
var url = string.IsNullOrEmpty(apiPath) ? apiHost :
|
|
$"{apiHost.TrimEnd('/')}/{apiPath.TrimStart('/')}";
|
|
var isCombineParam = false;
|
|
if (paramPosition == ParamPosition.Query && param != null)
|
|
{
|
|
url = $"{url}{(param.ToString().StartsWith("?") ? string.Empty : "?")}{param}";
|
|
isCombineParam = true;
|
|
}
|
|
|
|
//使用时间戳绕过CDN
|
|
if (useRandomTimeStamp)
|
|
url = $"{url}{(isCombineParam ? "&" : "?")}t={DateTime.Now.ToFileTime()}";
|
|
|
|
|
|
using (var httpClient = httpClientFactory.CreateClient())
|
|
{
|
|
httpClient.Timeout = TimeOut;
|
|
using (var request = new HttpRequestMessage(httpMethod, url))
|
|
{
|
|
if (requestHeaders != null && requestHeaders.Count > 0)
|
|
foreach (var key in requestHeaders.Keys)
|
|
request.Headers.Add(key, requestHeaders[key]);
|
|
|
|
if (paramPosition == ParamPosition.Body && param != null)
|
|
request.Content = new StringContent(contentType == ContentType_Json ? JsonConvert.SerializeObject(param) : param.ToString(), Encoding.UTF8, contentType);
|
|
|
|
using (var response = httpClient.SendAsync(request, httpCompletionOption).Result)
|
|
{
|
|
if (!response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Redirect && response.StatusCode != HttpStatusCode.Moved)
|
|
throw new Exception($"Reuqest {url} HttpCode {response.StatusCode}");
|
|
return new RestApiResult()
|
|
{
|
|
StatusCode = response.StatusCode,
|
|
Content = httpCompletionOption == HttpCompletionOption.ResponseContentRead ? response.Content.ReadAsStringAsync().Result :
|
|
string.Empty,
|
|
Headers = getResponseHeader ? response.Headers : null
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public class RestApiResult
|
|
{
|
|
public HttpStatusCode StatusCode { get; set; }
|
|
|
|
public string Content { get; set; }
|
|
|
|
public HttpResponseHeaders Headers { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 参数传递位置
|
|
/// </summary>
|
|
public enum ParamPosition
|
|
{
|
|
Query,
|
|
Body
|
|
}
|
|
}
|
|
|