mirror of
https://github.com/KevinWG/OSS.Tools.git
synced 2026-10-24 10:46:25 +08:00
243 lines
8.5 KiB
C#
243 lines
8.5 KiB
C#
#region Copyright (C) 2016 Kevin (OSS开源系列) 公众号:osscoder
|
||
|
||
/***************************************************************************
|
||
* 文件功能描述:Http请求 == 主请求实体
|
||
*
|
||
* 创建人: Kevin
|
||
* 创建人Email:1985088337@qq.com
|
||
*
|
||
*****************************************************************************/
|
||
|
||
#endregion
|
||
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Net.Http;
|
||
using System.Net.Http.Headers;
|
||
using System.Text;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using OSS.Http.Mos;
|
||
|
||
namespace OSS.Http
|
||
{
|
||
/// <summary>
|
||
/// 请求基类
|
||
/// </summary>
|
||
public class OsRest:HttpClient
|
||
{
|
||
public Encoding Encoding { get; set; } = Encoding.UTF8;
|
||
//private static readonly Dictionary<string,Action<HttpContentHeaders,string>> _notCanAddContentHeaderDics
|
||
// =new Dictionary<string, Action<HttpContentHeaders, string>>();
|
||
|
||
public OsRest():this(new HttpClientHandler(),true)
|
||
{
|
||
}
|
||
public OsRest(HttpMessageHandler handler)
|
||
: this(handler,true)
|
||
{
|
||
}
|
||
public OsRest(HttpMessageHandler handler,bool disposeHandler) : base(handler, disposeHandler)
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 执行请求方法
|
||
/// </summary>
|
||
/// <param name="request"></param>
|
||
/// <param name="completionOption"></param>
|
||
/// <param name="cancellationToken"></param>
|
||
/// <returns></returns>
|
||
public Task<HttpResponseMessage> RestSend(OsHttpRequest request,
|
||
HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead,
|
||
CancellationToken cancellationToken = new CancellationToken())
|
||
{
|
||
var reqMsg = ConfigureReqMsg(request);
|
||
|
||
if (request.TimeOutMilSeconds > 0)
|
||
this.Timeout = TimeSpan.FromMilliseconds(request.TimeOutMilSeconds);
|
||
|
||
return SendAsync(reqMsg, completionOption, cancellationToken);
|
||
}
|
||
|
||
#region 配置 ReqMsg信息
|
||
|
||
/// <summary>
|
||
/// 配置请求
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public HttpRequestMessage ConfigureReqMsg(OsHttpRequest request)
|
||
{
|
||
var reqMsg = new HttpRequestMessage();
|
||
|
||
reqMsg.RequestUri = string.IsNullOrEmpty(request.AddressUrl) ? request.Uri : new Uri(request.AddressUrl);
|
||
reqMsg.Method = new HttpMethod(request.HttpMothed.ToString());
|
||
|
||
ConfigReqContent(reqMsg, request); // 配置内容
|
||
return reqMsg;
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 配置使用的cotent
|
||
/// </summary>
|
||
/// <param name="reqMsg"></param>
|
||
/// <param name="req"></param>
|
||
/// <returns></returns>
|
||
private void ConfigReqContent(HttpRequestMessage reqMsg, OsHttpRequest req)
|
||
{
|
||
if (req.HttpMothed == HttpMothed.GET) return;
|
||
|
||
if (req.HasFile)
|
||
{
|
||
string boundary = GetBoundary();
|
||
var content= new MultipartFormDataContent(boundary);
|
||
|
||
WriteMultipartFormContent(content, req.FormParameters);
|
||
WriteMultipartFormFileContent(content, req.FileParameters);
|
||
|
||
reqMsg.Content = content;
|
||
req.RequestSet?.Invoke(reqMsg); // 位置不能变,防止外部修改 Content-Type
|
||
reqMsg.Content.Headers.TryAddWithoutValidation("Content-Type", $"multipart/form-data;boundary={boundary}");
|
||
}
|
||
else
|
||
{
|
||
string data = GetNormalFormData(req);
|
||
|
||
reqMsg.Content = new StringContent(data);
|
||
reqMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||
req.RequestSet?.Invoke(reqMsg);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
#region 请求数据的 内容 处理
|
||
|
||
#region 处理带文件上传的数据处理
|
||
/// <summary>
|
||
/// 创建 请求 分割界限
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private static string GetBoundary()
|
||
{
|
||
string pattern = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||
StringBuilder boundaryBuilder = new StringBuilder();
|
||
Random rnd = new Random();
|
||
for (int i = 0; i < 10; i++)
|
||
{
|
||
var index = rnd.Next(pattern.Length);
|
||
boundaryBuilder.Append(pattern[index]);
|
||
}
|
||
return $"---------{boundaryBuilder}";
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 上传文件请求中的分文件参数写入
|
||
/// </summary>
|
||
/// <param name="parentContent"></param>
|
||
/// <param name="formParams"></param>
|
||
private static void WriteMultipartFormContent(MultipartFormDataContent parentContent, List<FormParameter> formParams)
|
||
{
|
||
foreach (var param in formParams)
|
||
{
|
||
var formContent = new StringContent(param.Value.ToString());
|
||
parentContent.Add(formContent, param.Name);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 上传文件中的文件参数
|
||
/// </summary>
|
||
/// <param name="parentContent"></param>
|
||
/// <param name="filesParams"></param>
|
||
private static void WriteMultipartFormFileContent(MultipartFormDataContent parentContent,
|
||
List<FileParameter> filesParams)
|
||
{
|
||
foreach (var file in filesParams)
|
||
{
|
||
var formContent = new StreamContent(file.FileStream);
|
||
formContent.Headers.ContentType =
|
||
new MediaTypeHeaderValue(file.ContentType ?? "application/octet-stream");
|
||
parentContent.Add(formContent, file.Name, file.FileName);
|
||
}
|
||
}
|
||
|
||
|
||
#endregion
|
||
|
||
#region 不包含文件的数据处理(正常 get/post 请求)
|
||
/// <summary>
|
||
/// 写入请求的内容信息 (非文件上传请求)
|
||
/// </summary>
|
||
/// <param name="request"></param>
|
||
/// <returns></returns>
|
||
private static string GetNormalFormData(OsHttpRequest request)
|
||
{
|
||
var formstring = new StringBuilder();
|
||
foreach (var p in request.FormParameters)
|
||
{
|
||
if (formstring.Length > 1)
|
||
formstring.Append("&");
|
||
formstring.AppendFormat(p.ToString());
|
||
}
|
||
if (!string.IsNullOrEmpty(request.CustomBody))
|
||
{
|
||
if (formstring.Length > 1)
|
||
formstring.Append("&");
|
||
formstring.Append(request.CustomBody);
|
||
}
|
||
return formstring.ToString();
|
||
}
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
|
||
#region 请求辅助方法
|
||
/// <summary>
|
||
/// 写入数据方法(将数据写入 webrequest)
|
||
/// </summary>
|
||
/// <param name="stream"></param>
|
||
/// <param name="toWrite"></param>
|
||
/// <returns>写入的字节数量</returns>
|
||
private int WriteStringTo(Stream stream, string toWrite)
|
||
{
|
||
var bytes = Encoding.GetBytes(toWrite);
|
||
stream.Write(bytes, 0, bytes.Length);
|
||
return bytes.Length;
|
||
}
|
||
//protected static void AddStaticHeaderDictionary()
|
||
//{
|
||
// _notCanAddContentHeaderDics.Add("Accept", (r, v) => r.Accept = v);
|
||
// _notCanAddContentHeaderDics.Add("Content-Type", (r, v) => r.ContentType = v);
|
||
|
||
// _notCanAddContentHeaderDics.Add("Date", (r, v) =>
|
||
// {
|
||
// DateTime parsed;
|
||
// if (DateTime.TryParse(v, out parsed))
|
||
// {
|
||
// r.Date = parsed;
|
||
// }
|
||
// });
|
||
// _notCanAddContentHeaderDics.Add("Host", (r, v) => r.Host = v);
|
||
// _notCanAddContentHeaderDics.Add("Connection", (r, v) => r.Connection = v);
|
||
// _notCanAddContentHeaderDics.Add("Content-Length", (r, v) => r.ContentLength = Convert.ToInt64(v));
|
||
// _notCanAddContentHeaderDics.Add("Expect", (r, v) => r.Expect = v);
|
||
// _notCanAddContentHeaderDics.Add("If-Modified-Since", (r, v) => r. = Convert.ToDateTime(v));
|
||
// _notCanAddContentHeaderDics.Add("Referer", (r, v) => r.Referer = v);
|
||
// _notCanAddContentHeaderDics.Add("Transfer-Encoding", (r, v) => { r.TransferEncoding = v; r.SendChunked = true; });
|
||
// _notCanAddContentHeaderDics.Add("User-Agent", (r, v) => r.UserAgent = v);
|
||
//}
|
||
|
||
#endregion
|
||
}
|
||
}
|