/// <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; } }