|
@ -2,7 +2,9 @@ |
|
|
using Newtonsoft.Json; |
|
|
using Newtonsoft.Json; |
|
|
using System; |
|
|
using System; |
|
|
using System.Collections.Generic; |
|
|
using System.Collections.Generic; |
|
|
|
|
|
using System.Net; |
|
|
using System.Net.Http; |
|
|
using System.Net.Http; |
|
|
|
|
|
using System.Net.Http.Headers; |
|
|
using System.Text; |
|
|
using System.Text; |
|
|
|
|
|
|
|
|
namespace Binance.TradeRobot.Common.Http |
|
|
namespace Binance.TradeRobot.Common.Http |
|
@ -26,27 +28,34 @@ namespace Binance.TradeRobot.Common.Http |
|
|
/// <param name="apiHost"></param>
|
|
|
/// <param name="apiHost"></param>
|
|
|
/// <param name="apiPath"></param>
|
|
|
/// <param name="apiPath"></param>
|
|
|
/// <param name="param"></param>
|
|
|
/// <param name="param"></param>
|
|
|
/// <param name="headers"></param>
|
|
|
/// <param name="requestHeaders"></param>
|
|
|
/// <param name="httpMethod"></param>
|
|
|
/// <param name="httpMethod"></param>
|
|
|
/// <param name="contentType"></param>
|
|
|
/// <param name="contentType"></param>
|
|
|
/// <param name="paramPosition"></param>
|
|
|
/// <param name="paramPosition"></param>
|
|
|
/// <param name="enableRandomTimeStamp"></param>
|
|
|
/// <param name="useRandomTimeStamp"></param>
|
|
|
|
|
|
/// <param name="getResponseHeader"></param>
|
|
|
|
|
|
/// <param name="httpCompletionOption"></param>
|
|
|
|
|
|
/// <param name="httpClientName"></param>
|
|
|
/// <returns></returns>
|
|
|
/// <returns></returns>
|
|
|
public string SendRequest(string apiHost, |
|
|
public RestApiResult SendRequest(string apiHost, |
|
|
string apiPath, |
|
|
string apiPath, |
|
|
object param, |
|
|
object param, |
|
|
IDictionary<string, string> headers, |
|
|
IDictionary<string, string> requestHeaders, |
|
|
HttpMethod httpMethod, |
|
|
HttpMethod httpMethod, |
|
|
string contentType = ContentType_Json, |
|
|
string contentType = ContentType_Json, |
|
|
ParamPosition paramPosition = ParamPosition.Body, |
|
|
ParamPosition paramPosition = ParamPosition.Body, |
|
|
bool enableRandomTimeStamp = false) |
|
|
bool useRandomTimeStamp = false, |
|
|
|
|
|
bool getResponseHeader = false, |
|
|
|
|
|
HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead, |
|
|
|
|
|
string httpClientName = "") |
|
|
{ |
|
|
{ |
|
|
//Get和Delete强制使用QueryString形式传参
|
|
|
//Get和Delete强制使用QueryString形式传参
|
|
|
if (httpMethod == HttpMethod.Get || httpMethod == HttpMethod.Delete) |
|
|
if (httpMethod == HttpMethod.Get || httpMethod == HttpMethod.Delete) |
|
|
paramPosition = ParamPosition.Query; |
|
|
paramPosition = ParamPosition.Query; |
|
|
|
|
|
|
|
|
//拼接Url
|
|
|
//拼接Url
|
|
|
var url = $"{apiHost}{(apiHost.EndsWith("/") ? string.Empty : "/")}{(apiPath.StartsWith("/") ? apiPath.Substring(1) : apiPath)}"; |
|
|
var url = string.IsNullOrEmpty(apiPath) ? apiHost : |
|
|
|
|
|
$"{apiHost.TrimEnd('/')}/{apiPath.TrimStart('/')}"; |
|
|
var isCombineParam = false; |
|
|
var isCombineParam = false; |
|
|
if (paramPosition == ParamPosition.Query && param != null) |
|
|
if (paramPosition == ParamPosition.Query && param != null) |
|
|
{ |
|
|
{ |
|
@ -55,8 +64,8 @@ namespace Binance.TradeRobot.Common.Http |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//使用时间戳绕过CDN
|
|
|
//使用时间戳绕过CDN
|
|
|
if (enableRandomTimeStamp) |
|
|
if (useRandomTimeStamp) |
|
|
url = $"{url}{(isCombineParam ? "&" : "?")}t={DateTime.Now.DateTimeToStamp()}"; |
|
|
url = $"{url}{(isCombineParam ? "&" : "?")}t={DateTime.Now.ToFileTime()}"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using (var httpClient = httpClientFactory.CreateClient()) |
|
|
using (var httpClient = httpClientFactory.CreateClient()) |
|
@ -64,22 +73,38 @@ namespace Binance.TradeRobot.Common.Http |
|
|
httpClient.Timeout = TimeOut; |
|
|
httpClient.Timeout = TimeOut; |
|
|
using (var request = new HttpRequestMessage(httpMethod, url)) |
|
|
using (var request = new HttpRequestMessage(httpMethod, url)) |
|
|
{ |
|
|
{ |
|
|
if (headers != null && headers.Count > 0) |
|
|
if (requestHeaders != null && requestHeaders.Count > 0) |
|
|
foreach (var key in headers.Keys) |
|
|
foreach (var key in requestHeaders.Keys) |
|
|
request.Headers.Add(key, headers[key]); |
|
|
request.Headers.Add(key, requestHeaders[key]); |
|
|
|
|
|
|
|
|
if (paramPosition == ParamPosition.Body && param != null) |
|
|
if (paramPosition == ParamPosition.Body && param != null) |
|
|
request.Content = new StringContent(contentType == ContentType_Json ? JsonConvert.SerializeObject(param) : param.ToString(), Encoding.UTF8, contentType); |
|
|
request.Content = new StringContent(contentType == ContentType_Json ? JsonConvert.SerializeObject(param) : param.ToString(), Encoding.UTF8, contentType); |
|
|
|
|
|
|
|
|
using (var response = httpClient.SendAsync(request).Result) |
|
|
using (var response = httpClient.SendAsync(request, httpCompletionOption).Result) |
|
|
{ |
|
|
{ |
|
|
if (!response.IsSuccessStatusCode) |
|
|
if (!response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Redirect && response.StatusCode != HttpStatusCode.Moved) |
|
|
throw new Exception($"HttpCode {response.StatusCode}"); |
|
|
throw new Exception($"Reuqest {url} HttpCode {response.StatusCode}"); |
|
|
return response.Content.ReadAsStringAsync().Result; |
|
|
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>
|
|
|