/// <summary> /// 用于以 POST 方式向目标地址提交表达数据 /// 使用 application/x-www-form-urlencoded 编码方式 /// 不支持上传文件, 若上传文件, 请使用<see cref="HttpPostFileRequestClient"/> /// </summary> public sealed class HttpPostRequestClient { #region - Private - private List<KeyValuePair<string, string>> _postDatas; #endregion /// <summary> /// 获取或设置数据字符编码, 默认使用<see cref="System.Text.Encoding.UTF8"/> /// </summary> public Encoding Encoding { get; set; } = Encoding.UTF8; /// <summary> /// 获取或设置 UserAgent /// </summary> public string UserAgent { get; set; } = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"; /// <summary> /// 获取或设置 Accept /// </summary> public string Accept { get; set; } = "*/*"; /// <summary> /// 获取或设置 Referer /// </summary> public string Referer { get; set; } /// <summary> /// 获取或设置 Cookie 容器 /// </summary> public CookieContainer CookieContainer { get; set; } = new CookieContainer(); /// <summary> /// 初始化一个用于以 POST 方式向目标地址提交不包含文件表单数据<see cref="HttpPostRequestClient"/>实例 /// </summary> public HttpPostRequestClient() { this._postDatas = new List<KeyValuePair<string, string>>(); } /// <summary> /// 设置表单数据字段, 用于存放文本类型数据 /// </summary> /// <param name="fieldName">指定的字段名称</param> /// <param name="fieldValue">指定的字段值</param> public void SetField(string fieldName, string fieldValue) { this._postDatas.Add(new KeyValuePair<string, string>(fieldName, fieldValue)); } /// <summary> /// 以POST方式向目标地址提交表单数据 /// </summary> /// <param name="url">目标地址, http(s)://sample.com</param> /// <returns>目标地址的响应</returns> public HttpWebResponse Post(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.CookieContainer = this.CookieContainer; var postData = string.Join("&", this._postDatas.Select(p => $"{p.Key}={p.Value}")); using(var requestStream = request.GetRequestStream()) { var bytes = this.Encoding.GetBytes(postData); requestStream.Write(bytes, 0, bytes.Length); } return request.GetResponse() as HttpWebResponse; } /// <summary> /// 以POST方式向目标地址提交表单数据 /// </summary> /// <param name="url">目标地址, http(s)://sample.com</param> /// <returns>目标地址的响应</returns> public async Task<HttpWebResponse> PostAsync(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.CookieContainer = this.CookieContainer; var postData = string.Join("&", this._postDatas.Select(p => $"{p.Key}={p.Value}")); using (var requestStream = await request.GetRequestStreamAsync()) { var bytes = this.Encoding.GetBytes(postData); requestStream.Write(bytes, 0, bytes.Length); } return await request.GetResponseAsync() as HttpWebResponse; } }
/// <summary> /// 用于以 POST 方式向目标地址提交表单数据, 仅适用于包含文件的请求 /// </summary> public sealed class HttpPostFileRequestClient { #region - Private - private string _boundary; private List<byte[]> _postDatas; #endregion /// <summary> /// 获取或设置数据字符编码, 默认使用<see cref="System.Text.Encoding.UTF8"/> /// </summary> public Encoding Encoding { get; set; } = Encoding.UTF8; /// <summary> /// 获取或设置 UserAgent /// </summary> public string UserAgent { get; set; } = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"; /// <summary> /// 获取或设置 Accept /// </summary> public string Accept { get; set; } = "*/*"; /// <summary> /// 获取或设置 Referer /// </summary> public string Referer { get; set; } /// <summary> /// 获取或设置 Cookie 容器 /// </summary> public CookieContainer CookieContainer { get; set; } = new CookieContainer(); /// <summary> /// 初始化一个用于以 POST 方式向目标地址提交表单数据的<see cref="HttpPostFileRequestClient"/>实例 /// </summary> public HttpPostFileRequestClient() { this._boundary = DateTime.Now.Ticks.ToString("X"); this._postDatas = new List<byte[]>(); } /// <summary> /// 设置表单数据字段, 用于存放文本类型数据 /// </summary> /// <param name="fieldName">指定的字段名称</param> /// <param name="fieldValue">指定的字段值</param> public void SetField(string fieldName, string fieldValue) { var field = $"--{this._boundary}\r\n" + $"Content-Disposition: form-data;name=\"{fieldName}\"\r\n\r\n" + $"{fieldValue}\r\n"; this._postDatas.Add(this.Encoding.GetBytes(field)); } /// <summary> /// 设置表单数据字段, 用于文件类型数据 /// </summary> /// <param name="fieldName">字段名称</param> /// <param name="fileName">文件名</param> /// <param name="contentType">内容类型, 传入 null 将默认使用 application/octet-stream</param> /// <param name="fs">文件流</param> public void SetField(string fieldName, string fileName, string contentType, Stream fs) { var fileBytes = new byte[fs.Length]; using (fs) { fs.Read(fileBytes, 0, fileBytes.Length); } SetField(fieldName, fileName, contentType, fileBytes); } /// <summary> /// 设置表单数据字段, 用于文件类型数据 /// </summary> /// <param name="fieldName">字段名称</param> /// <param name="fileName">文件名</param> /// <param name="contentType">内容类型, 传入 null 将默认使用 application/octet-stream</param> /// <param name="fileBytes">文件字节数组</param> public void SetField(string fieldName, string fileName, string contentType, byte[] fileBytes) { var field = $"--{this._boundary}\r\n" + $"Content-Disposition: form-data; name=\"{fieldName}\";filename=\"{fileName}\"\r\n" + $"Content-Type:{contentType ?? "application/octet-stream"}\r\n\r\n"; this._postDatas.Add(this.Encoding.GetBytes(field)); this._postDatas.Add(fileBytes); this._postDatas.Add(this.Encoding.GetBytes("\r\n")); } /// <summary> /// 以POST方式向目标地址提交表单数据 /// </summary> /// <param name="url">目标地址, http(s)://sample.com</param> /// <returns>目标地址的响应</returns> public HttpWebResponse Post(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Method = "POST"; request.ContentType = "multipart/form-data;boundary=" + _boundary; request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.CookieContainer = this.CookieContainer; var end = $"--{this._boundary}--\r\n"; this._postDatas.Add(this.Encoding.GetBytes(end)); var requestStream = request.GetRequestStream(); foreach (var item in this._postDatas) { requestStream.Write(item, 0, item.Length); } return request.GetResponse() as HttpWebResponse; } /// <summary> /// 以POST方式向目标地址提交表单数据 /// </summary> /// <param name="url">目标地址, http(s)://sample.com</param> /// <returns>目标地址的响应</returns> public async Task<HttpWebResponse> PostAsync(string url) { if (string.IsNullOrWhiteSpace(url)) throw new ArgumentNullException(nameof(url)); HttpWebRequest request = null; if (url.ToLowerInvariant().StartsWith("https")) { request = WebRequest.Create(url) as HttpWebRequest; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((s, c, ch, ss) => { return true; }); request.ProtocolVersion = HttpVersion.Version11; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls; request.KeepAlive = true; ServicePointManager.CheckCertificateRevocationList = true; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.Expect100Continue = false; } else { request = WebRequest.Create(url) as HttpWebRequest; } request.Method = "POST"; request.ContentType = "multipart/form-data;boundary=" + _boundary; request.UserAgent = this.UserAgent; request.Accept = this.Accept; request.Referer = this.Referer; request.CookieContainer = this.CookieContainer; var end = $"--{this._boundary}--\r\n"; this._postDatas.Add(this.Encoding.GetBytes(end)); var requestStream = await request.GetRequestStreamAsync(); foreach (var item in this._postDatas) { await requestStream.WriteAsync(item, 0, item.Length); } return await request.GetResponseAsync() as HttpWebResponse; } }