本文最后更新于 2024-05-07,文章可能存在过时内容,如有过时内容欢迎留言或者联系我进行反馈。
代码示例 {#%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B}
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Reflection;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace Common
{
public sealed class HttpUtil
{
private static readonly HttpUtil httpUtility = new HttpUtil();
private HttpUtil()
{ }
public static HttpUtil GetInstance { get => httpUtility; }
#region 异步请求
/// <summary>异步请求</summary>
/// <param name="requestParameters"></param>
/// <returns></returns>
public async Task<ResponseResult> HttpRequestAsync(RequestParameters requestParameters)
{
//string result = string.Empty;
ResponseResult result = new ResponseResult();
try
{
if (requestParameters.Query?.Count > 0)
requestParameters.Url += BuildQuery(requestParameters.Query);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestParameters.Url);
httpWebRequest.Method = requestParameters.Method.ToString();
httpWebRequest.ContentType = requestParameters.ContentType;
httpWebRequest.Timeout = requestParameters.TimeOut;
httpWebRequest.KeepAlive = true;
httpWebRequest.Accept = "/";
if (requestParameters.Headers?.Count > 0)
{
foreach (var item in requestParameters.Headers)
httpWebRequest.Headers.Add(item.Key, item.Value.ToString());
}
if (!string.IsNullOrEmpty(requestParameters.PostData))
{
byte[] data = Encoding.UTF8.GetBytes(requestParameters.PostData);
httpWebRequest.ContentLength = data.Length;
using (Stream stream = await httpWebRequest.GetRequestStreamAsync())
{
stream.Write(data, 0, data.Length);
}
}
using (HttpWebResponse httpWebResponse = (HttpWebResponse)await httpWebRequest.GetResponseAsync())
{
for (int i = 0; i < httpWebResponse.Headers.Count; i++)
result.Headers.Add(httpWebResponse.Headers.Keys[i], httpWebResponse.Headers[i]);
using (StreamReader reader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.UTF8))
result.Body = await reader.ReadToEndAsync();
}
}
catch (Exception ex)
{
throw;
}
return result;
}
#endregion 异步请求
#region 同步请求
public ResponseResult HttpRequest(RequestParameters requestParameters)
{
//string result = string.Empty;
ResponseResult result = new ResponseResult();
try
{
if (requestParameters.Query?.Count > 0)
requestParameters.Url += BuildQuery(requestParameters.Query);
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(requestParameters.Url);
httpWebRequest.Method = requestParameters.Method.ToString();
httpWebRequest.ContentType = requestParameters.ContentType;
httpWebRequest.Timeout = requestParameters.TimeOut;
if (requestParameters.Headers?.Count > 0)
{
foreach (var item in requestParameters.Headers)
httpWebRequest.Headers.Add(item.Key, item.Value.ToString());
}
if (!string.IsNullOrEmpty(requestParameters.PostData))
{
byte[] data = Encoding.UTF8.GetBytes(requestParameters.PostData);
httpWebRequest.ContentLength = data.Length;
using (Stream stream = httpWebRequest.GetRequestStream())
stream.Write(data, 0, data.Length);
}
using (HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
using (StreamReader reader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.UTF8))
result.Body = reader.ReadToEnd();
foreach (var key in httpWebResponse.Headers.AllKeys)
result.Headers.Add(key, httpWebResponse.Headers[key]);
}
}
catch (Exception ex)
{
throw;
}
return result;
}
#endregion 同步请求
/// <summary>拼接参数</summary>
/// <param name="parameters"></param>
/// <param name="encode"></param>
/// <returns></returns>
private string BuildQuery(Dictionary<string, object> parameters, string encode = "utf8")
{
StringBuilder postData = new StringBuilder("?");
bool hasParam = false;
foreach (var item in parameters)
{
string key = item.Key;
string value = item.Value.ToString();
if (!string.IsNullOrEmpty(key))
{
if (hasParam)
postData.Append("&");
postData.Append($"{key}=");
if (encode == "gb2312")
postData.Append(System.Web.HttpUtility.UrlEncode(value, Encoding.GetEncoding("gb2312")));
else if (encode == "utf8")
postData.Append(System.Web.HttpUtility.UrlEncode(value, Encoding.UTF8));
else
postData.Append(value);
hasParam = true;
}
}
return postData.ToString();
}
}
#region 请求参数
/// <summary>请求方式类型</summary>
public enum MethodType
{
GET,
POST,
PUT,
DELETE
}
/// <summary>请求参数</summary>
public class RequestParameters
{
#region 字段
private const string nonce = "nonc";
private const string timestamp = "timestamp";
private Dictionary<string, object> _headers = new Dictionary<string, object>();
#endregion 字段
#region 属性
/// <summary>地址</summary>
public string Url { get; set; }
/// <summary>请求方式</summary>
public MethodType Method { get; set; }
/// <summary>内容格式</summary>
public string ContentType { get; set; }
/// <summary>请求头</summary>
//public Dictionary<string, object> Headers
//{
// get => new Dictionary<string, object>
// {
// { nonce, RandomStringBuilderUtility.Create(10) },
// { timestamp, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
// };
// set => _headers = value;
//}
/// <summary>请求头</summary>
public Dictionary<string, object> Headers { get; set; } = new Dictionary<string, object>
{
{ nonce, RandomStringBuilderUtil.Create(10) },
{ timestamp, DateTimeOffset.UtcNow.ToUnixTimeSeconds() }
};
/// <summary>请求参数</summary>
public Dictionary<string, object> Query { get; set; }
/// <summary>请求数据</summary>
public string PostData { get; set; }
/// <summary>超时时间</summary>
public int TimeOut { get; set; } = 1000 * 60;
#endregion 属性
}
/// <summary>响应结果</summary>
public class ResponseResult
{
/// <summary>响应体</summary>
public string Body { get; set; }
/// <summary>响应头</summary>
public Dictionary<string, object> Headers { get; set; } = new Dictionary<string, object>();
}
/// <summary>内容格式类型</summary>
public class ContentType
{
public static readonly string Text = "text/plain";
public static readonly string JSON = "application/json";
public static readonly string JavaScript = "application/javascript";
public static readonly string XML = "application/xml";
public static readonly string TextXML = "text/xml";
public static readonly string HTML = "text/html";
public static readonly string FormData = "multipart/form-data";
public static readonly string UrlEncoded = "x-www-form-urlencoded";
}
#endregion 请求参数
}
在上述代码中,HttpUtil
类使用了单例模式来确保只有一个实例被创建。通过私有的构造函数,防止外部直接实例化该类。通过静态属性 GetInstance
来获取类的唯一实例,如果实例不存在,则在多线程环境下使用双重检查锁定来创建实例。