• C# 模拟 HTTP POST请求


        /// <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}
    " +
                            $"Content-Disposition: form-data;name="{fieldName}"
    
    " +
                            $"{fieldValue}
    ";
                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}
    " +
                            $"Content-Disposition: form-data; name="{fieldName}";filename="{fileName}"
    " +
                            $"Content-Type:{contentType ?? "application/octet-stream"}
    
    ";
                this._postDatas.Add(this.Encoding.GetBytes(field));
                this._postDatas.Add(fileBytes);
                this._postDatas.Add(this.Encoding.GetBytes("
    "));
            }
            
            /// <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}--
    ";
                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}--
    ";
                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;
            }
        }
    
  • 相关阅读:
    LINUX核心命令实战总结七——文件备份与压缩命令
    LINUX核心命令实战总结六——信息显示与搜索文件命令
    LINUX核心命令实战总结五——文件过滤及内容编辑处理命令二
    LINUX核心命令实战总结四——文件过滤及内容编辑处理命令一
    LINUX核心命令实战总结三——文件和目录操作命令二
    LINUX核心命令实战总结二——文件和目录操作命令一
    LINUX核心命令实战总结一——关机、重启、注销命令
    python进阶十——mysql初识
    python进阶九——并发编程之协程
    入职培训第一天
  • 原文地址:https://www.cnblogs.com/aning2015/p/10458866.html
Copyright © 2020-2023  润新知