using System.Collections.Specialized;
using System.Net.Http.Headers;
using System.Text;
using DS.Module.Core.Extensions;
using Newtonsoft.Json;
namespace DS.Module.Core
{
///
/// 提供对HTTP请求的低级别访问
///
public class ApiFox
{
///
/// 基URI
///
public Uri? BaseUri { get; set; }
///
/// 默认请求头
///
public IDictionary DefaultHeaders { get; private set; }
///
/// 在发送网络请求之前的事件
///
public event EventHandler? BeforeSend;
///
/// 在发送网络请求完成时的事件
///
public event EventHandler? Completed;
///
/// 初始化
///
public ApiFox()
{
DefaultHeaders = new Dictionary();
}
///
/// 发起请求
///
/// 请求结果的类型
/// 请求Url
/// 查询字符串的键值对
///
/// 为null或空字符串
public async Task> GetAsync(string url, NameValueCollection? keyValues = null)
{
string queryString = string.Empty;
if (keyValues != null && keyValues.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (string key in keyValues.Keys)
{
var values = keyValues.GetValues(key);
if (values?.Length > 0)
{
for (int i = 0; i < values.Length; i++)
{
sb.Append($"&{key}={values[i]}");
}
}
}
if (sb.Length > 0) //移除首个&符
sb.Remove(0, 1);
queryString = sb.ToString();
}
if (!queryString.IsNullOrEmpty())
url = url.LastOrDefault() == '?' ? url + queryString : url + "?" + queryString;
var result = await SendRequestAsync(HttpMethod.Get, url);
if (!result.Succeeded)
return DataResult.Failed(result.Message, result.MultiCode);
var response = result.Data;
string json = await response.Content.ReadAsStringAsync();
return DataResult.Success(JsonConvert.DeserializeObject(json));
}
///
/// 发起请求
///
/// 请求结果的类型
/// 请求Url
/// 请求参数对象
///
/// 为null或空字符串
public async Task> PostAsync(string url, object? requestParams = null)
{
var result = await SendRequestAsync(HttpMethod.Post, url, requestParams);
if (!result.Succeeded)
return DataResult.Failed(result.Message, result.MultiCode);
var response = result.Data;
string json = await response.Content.ReadAsStringAsync();
return DataResult.Success(JsonConvert.DeserializeObject(json));
}
///
/// 发起HTTP请求
///
/// 请求方法
/// 请求Url
/// 请求参数
///
/// 为null
/// 为null或空字符串
public async Task> SendRequestAsync(HttpMethod method, string url, object? requestParams = null)
{
ArgumentNullException.ThrowIfNull(method);
ArgumentException.ThrowIfNullOrEmpty(url);
Uri? reqUri = default;
if (BaseUri == null)
{
if (!Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out Uri? uri))
throw new ArgumentException("给定的URL格式无效", nameof(url));
reqUri = new Uri(url);
}
else
{
reqUri = new(BaseUri, url);
}
HttpClient http = new();
http.DefaultRequestHeaders.Add("User-Agent", $"X-{nameof(ApiFox)}");
if (DefaultHeaders.Count > 0)
foreach (var header in DefaultHeaders)
http.DefaultRequestHeaders.Add(header.Key, header.Value);
if (!http.DefaultRequestHeaders.Contains("Accept"))
http.DefaultRequestHeaders.Add("Accept", "application/json, text/plain");
OnBeforeSend(new BeforeSendEventArgs
{
RequestHeaders = http.DefaultRequestHeaders,
RequestParameter = requestParams,
RequestUri = reqUri
});
try
{
HttpResponseMessage? response = null;
if (method == HttpMethod.Get)
{
response = await http.GetAsync(reqUri);
}
else if (method == HttpMethod.Post)
{
var jsonRequest = new StringContent(JsonConvert.SerializeObject(requestParams), Encoding.UTF8, "application/json");
response = await http.PostAsync(reqUri, jsonRequest);
}
else if (method == HttpMethod.Put)
{
var jsonRequest = new StringContent(JsonConvert.SerializeObject(requestParams), Encoding.UTF8, "application/json");
response = await http.PutAsync(reqUri, jsonRequest);
}
else if (method == HttpMethod.Delete)
{
response = await http.DeleteAsync(reqUri);
}
else
{
throw new NotSupportedException($"不支持的请求方法:{method.Method}");
}
OnCompleted(new CompleteEventArgs
{
RequestUri = reqUri,
Response = response
});
if (!response.IsSuccessStatusCode)
return DataResult.FailedData(response, string.Format(MultiLanguageConst.HttpRequestFailed, $"{response.StatusCode}"));
return DataResult.Success(response);
}
finally
{
http?.Dispose();
}
}
///
/// 在发送网络请求之前调用
///
/// 事件参数
protected virtual void OnBeforeSend(BeforeSendEventArgs e)
{
BeforeSend?.Invoke(this, e);
}
///
/// 在发送网络请求完成时调用
///
/// 事件参数
protected virtual void OnCompleted(CompleteEventArgs e)
{
Completed?.Invoke(this, e);
}
}
///
/// 发送网络请求之前的事件参数
///
public class BeforeSendEventArgs : EventArgs
{
///
/// 远程请求的URI
///
public Uri RequestUri { get; internal set; }
///
/// 请求标头
///
public HttpRequestHeaders RequestHeaders { get; internal set; }
///
/// 请求参数
///
public object? RequestParameter { get; set; }
}
///
/// 发送网络请求完成的事件参数
///
public class CompleteEventArgs : EventArgs
{
///
/// 远程请求的URI
///
public Uri RequestUri { get; internal set; }
///
/// 网络响应对象
///
public HttpResponseMessage Response { get; internal set; }
}
}