Files
OSS.Tools/OSS.Http/OsRest.cs
T

243 lines
8.5 KiB
C#
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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
}
}