C# 模拟HTTP请求 GET POST + 文件上传

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using System.Windows.Forms;

namespace CadCoreApp
{
    public static class HttpHelper
    {

        /// <summary>
        /// http/https请求响应
        /// </summary>
        /// <param name="getOrPost"></param>
        /// <param name="url">地址(要带上http或https)</param>
        /// <param name="headers">请求头</param>
        /// <param name="parameters">提交数据</param>
        /// <param name="dataEncoding">编码类型 utf-8</param>
        /// <param name="contentType">application/x-www-form-urlencoded</param>
        /// <returns></returns>
        public static HttpWebResponse HttpRequest(
            string getOrPost,
            string url,
            Dictionary<string, string> headers,
            Dictionary<string, string> parameters,
            Encoding dataEncoding,
            string contentType
            )
        {
            var request = CreateRequest(getOrPost, url, headers, parameters, dataEncoding, contentType);

            //如果需要POST数据  
            if (getOrPost == "POST" && !(parameters == null || parameters.Count == 0))
            {
                var data = FormatPostParameters(parameters, dataEncoding, contentType);

                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                    stream.Close();
                }
            }

            WebResponse Res = null;
            try
            {
                Res = request.GetResponse();
            }
            catch (WebException ex)
            {
                Res = (HttpWebResponse)ex.Response;
            }
            catch (Exception e)
            {
                throw e;
            }

            if (null == Res)
            {
                return request.GetResponse() as HttpWebResponse;
            }

            return (HttpWebResponse)Res;
        }


        /// <summary>
        /// 创建HTTP请求对象
        /// </summary>
        /// <param name="getOrPost"></param>
        /// <param name="url"></param>
        /// <param name="headers"></param>
        /// <param name="parameters"></param>
        /// <param name="paraEncoding"></param>
        /// <param name="contentType"></param>
        /// <returns></returns>
        private static HttpWebRequest CreateRequest(
            string getOrPost
            , string url
            , Dictionary<string, string> headers
            , Dictionary<string, string> parameters
            , Encoding paraEncoding
            , string contentType
            )
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentNullException("url");
            }

            if (parameters != null && parameters.Count > 0 && paraEncoding == null)
            {
                throw new ArgumentNullException("requestEncoding");
            }

            HttpWebRequest request = null;
            //判断是否是https  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback =
                    new RemoteCertificateValidationCallback(CheckValidationResult);
                request = WebRequest.Create(url) as HttpWebRequest;
                request.ProtocolVersion = HttpVersion.Version10;
            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }

            if (getOrPost == "GET")
            {
                request.Method = "GET";

                if (parameters != null && parameters.Count > 0)
                {
                    url = FormatGetParametersToUrl(url, parameters, paraEncoding);
                }
            }
            else
            {
                request.Method = "POST";
            }

            if (contentType == null)
            {
                request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
            }
            else
            {
                request.ContentType = contentType;
            }

            //POST的数据大于1024字节的时候,如果不设置会分两步
            request.ServicePoint.Expect100Continue = false;
            request.ServicePoint.ConnectionLimit = int.MaxValue;

            if (headers != null)
            {
                FormatRequestHeaders(headers, request);
            }

            return request;
        }


        /// <summary>
        /// 格式化请求头信息
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="request"></param>
        private static void FormatRequestHeaders(Dictionary<string, string> headers, HttpWebRequest request)
        {
            foreach (var hd in headers)
            {
                //因为HttpWebRequest中很多标准标头都被封装成只能通过属性设置,添加的话会抛出异常
                switch (hd.Key.ToLower())
                {
                    case "connection":
                        request.KeepAlive = false;
                        break;
                    case "content-type":
                        request.ContentType = hd.Value;
                        break;
                    case "transfer-enconding":
                        request.TransferEncoding = hd.Value;
                        break;
                    default:
                        request.Headers.Add(hd.Key, hd.Value);
                        break;
                }
            }
        }


        /// <summary>
        /// 格式化Get请求参数
        /// </summary>
        /// <param name="url">URL</param>
        /// <param name="parameters">参数</param>
        /// <param name="paraEncoding">编码格式</param>
        /// <returns></returns>

        private static string FormatGetParametersToUrl(string url, Dictionary<string, string> parameters, Encoding paraEncoding)
        {
            if (url.IndexOf("?") < 0)
                url += "?";
            int i = 0;
            string sendContext = "";
            foreach (var parameter in parameters)
            {
                if (i > 0)
                {
                    sendContext += "&";
                }

                sendContext += HttpUtility.UrlEncode(parameter.Key, paraEncoding)
                       + "=" + HttpUtility.UrlEncode(parameter.Value, paraEncoding);
                ++i;
            }

            url += sendContext;
            return url;
        }


        /// <summary>
        /// 格式化Post请求参数
        /// </summary>
        /// <param name="parameters">编码格式</param>
        /// <param name="dataEncoding">编码格式</param>
        /// <param name="contentType">类型</param>
        /// <returns></returns>
        private static byte[] FormatPostParameters(Dictionary<string, string> parameters, Encoding dataEncoding, string contentType)
        {
            string sendContext = "";
            int i = 0;
            if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Trim() == "application/json")
            {
                sendContext = "{";
            }

            foreach (var para in parameters)
            {
                if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Trim() == "application/json")
                {
                    if (i > 0)
                    {
                        if (para.Value.StartsWith("{"))
                        {
                            sendContext += string.Format(@",""{0}"":{1}", para.Key, para.Value);
                        }
                        else
                        {
                            sendContext += string.Format(@",""{0}"":""{1}""", para.Key, para.Value);
                        }

                    }
                    else
                    {
                        if (para.Value.StartsWith("{"))
                        {
                            sendContext += string.Format(@"""{0}"":{1}", para.Key, para.Value);
                        }
                        else
                        {
                            sendContext += string.Format(@"""{0}"":""{1}""", para.Key, para.Value);
                        }

                    }
                }
                else
                {
                    if (i > 0)
                    {
                        sendContext += string.Format("&{0}={1}", para.Key, HttpUtility.UrlEncode(para.Value, dataEncoding));
                    }
                    else
                    {
                        sendContext = string.Format("{0}={1}", para.Key, HttpUtility.UrlEncode(para.Value, dataEncoding));
                    }
                }

                i++;
            }

            if (!string.IsNullOrEmpty(contentType) && contentType.ToLower().Trim() == "application/json")
            {
                sendContext += "}";
            }

            byte[] data = dataEncoding.GetBytes(sendContext);
            return data;
        }


        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain,
            SslPolicyErrors errors)
        {
            return true; //总是接受  
        }

        /// <summary>
        /// 正常GET
        /// </summary>
        /// <param name="Url"></param>
        /// <returns></returns>
        //contentType application/json or application/xml
        public static string HttpGet(string Url)
        {
            try
            {
                string contentType = "application/json; charset=UTF-8";
                string retString = string.Empty;

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                request.Method = "GET";
                request.ContentType = contentType;
                request.Accept = contentType;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(myResponseStream);
                retString = streamReader.ReadToEnd();
                streamReader.Close();
                myResponseStream.Close();
                return retString;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 正常通用请求
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="postDataStr"></param>
        /// <returns></returns>
        public static string HttpPost(string Url, string postDataStr)
        {
            string retString = string.Empty;
            string contentType = "application/json; charset=UTF-8";
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                request.Method = "POST";
                request.ContentType = contentType;
                request.Accept = contentType;
                request.Timeout = 600000;//设置超时时间
                request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
                request.Headers.Add(String.Format("Authorization: Bearer {0}", Common.AccessToken));

                Stream requestStream = request.GetRequestStream();
                StreamWriter streamWriter = new StreamWriter(requestStream);
                streamWriter.Write(postDataStr);
                streamWriter.Close();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(responseStream);
                retString = streamReader.ReadToEnd();
                streamReader.Close();
                responseStream.Close();
               
            }
            catch (Exception ex)
            {
                if (ex.GetType() == typeof(WebException))//捕获400错误
                {
                    var response = ((WebException)ex).Response;
                    Stream responseStream = response.GetResponseStream();
                    StreamReader streamReader = new StreamReader(responseStream);
                    retString = streamReader.ReadToEnd();
                    streamReader.Close();
                    responseStream.Close();
                }
                else
                {
                    retString = ex.ToString();
                }
            }

            return retString;
        }

        /// <summary>
        /// 验证GET请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="postVars"></param>
        /// <returns></returns>
        public static string ALHttpGet(string url ,string postVars)
        {
            try
            {
                string contentType = "application/json; charset=UTF-8";
                string retString = string.Empty;
                url = String.Format(url + "?{0}", postVars);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.ContentType = contentType;
                request.Accept = contentType;
                request.Headers.Add(String.Format("Authorization: Bearer {0}", Common.AccessToken));

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream myResponseStream = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(myResponseStream);
                retString = streamReader.ReadToEnd();
                streamReader.Close();
                myResponseStream.Close();
                return retString;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 验证通用请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="verb">POST PUT</param>
        /// <param name="postDataStr"></param>
        /// <returns></returns>
        public static string ALHttpRequest(string url,string verb, string postDataStr)
        {
            string retString = string.Empty;
            string contentType = "application/json; charset=UTF-8";
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = verb;
                request.ContentType = contentType;
                request.Accept = contentType;
                request.Timeout = 600000;//设置超时时间
                request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
                request.Headers.Add(String.Format("Authorization: Bearer {0}", Common.AccessToken));

                Stream requestStream = request.GetRequestStream();
                StreamWriter streamWriter = new StreamWriter(requestStream);
                streamWriter.Write(postDataStr);
                streamWriter.Close();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                Stream responseStream = response.GetResponseStream();
                StreamReader streamReader = new StreamReader(responseStream);
                retString = streamReader.ReadToEnd();
                streamReader.Close();
                responseStream.Close();

            }
            catch (Exception ex)
            {
                if (ex.GetType() == typeof(WebException))//捕获400错误
                {
                    var response = ((WebException)ex).Response;
                    Stream responseStream = response.GetResponseStream();
                    StreamReader streamReader = new StreamReader(responseStream);
                    retString = streamReader.ReadToEnd();
                    streamReader.Close();
                    responseStream.Close();
                }
                else
                {
                    retString = ex.ToString();
                }
            }

            return retString;
        }

        /// </summary> 
        /// 带验证将本地文件上传到指定的服务器(HttpWebRequest方法) 
        /// </summary> 
        /// <param name="address">文件上传到的服务器</param> 
        /// <param name="fileNamePath">要上传的本地文件(全路径)</param> 
        /// <param name="saveName">文件上传后的名称</param> 
        /// <returns>成功返回1,失败返回0</returns> 
        private static int ALUpload_Request(string url, string fileNamePath, string saveName)
        {
            int returnValue = 0;

            // 要上传的文件 
            FileStream fs = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read);
            BinaryReader r = new BinaryReader(fs);

            //时间戳 
            string strBoundary = "----------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + strBoundary + "\r\n");

            //请求头部信息 
            StringBuilder sb = new StringBuilder();
            sb.Append("--");
            sb.Append(strBoundary);
            sb.Append("\r\n");
            sb.Append("Content-Disposition: form-data; name=\"");
            sb.Append("file");
            sb.Append("\"; filename=\"");
            sb.Append(saveName);
            sb.Append("\"");
            sb.Append("\r\n");
            sb.Append("Content-Type: ");
            sb.Append("application/octet-stream");
            sb.Append("\r\n");
            sb.Append("\r\n");
            string strPostHeader = sb.ToString();
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(strPostHeader);

            // 根据uri创建HttpWebRequest对象 
            HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
            httpReq.Method = "POST";
            httpReq.Headers.Add(String.Format("Authorization: Bearer {0}", Common.AccessToken));
            //对发送的数据不使用缓存 
            httpReq.AllowWriteStreamBuffering = false;

            //设置获得响应的超时时间(300秒) 
            httpReq.Timeout = 300000;
            httpReq.ContentType = "multipart/form-data; boundary=" + strBoundary;
            long length = fs.Length + postHeaderBytes.Length + boundaryBytes.Length;
            long fileLength = fs.Length;
            httpReq.ContentLength = length;
            try
            {
             
                //每次上传4k 
                int bufferLength = 4096;
                byte[] buffer = new byte[bufferLength];

                //已上传的字节数 
                long offset = 0;

                //开始上传时间 
                DateTime startTime = DateTime.Now;
                int size = r.Read(buffer, 0, bufferLength);
                Stream postStream = httpReq.GetRequestStream();

                //发送请求头部消息 
                postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
                while (size > 0)
                {
                    postStream.Write(buffer, 0, size);
                    offset += size;
                    TimeSpan span = DateTime.Now - startTime;
                    double second = span.TotalSeconds;
                    Application.DoEvents();
                    size = r.Read(buffer, 0, bufferLength);
                }
                //添加尾部的时间戳 
                postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                postStream.Close();

                //获取服务器端的响应 
                WebResponse webRespon = httpReq.GetResponse();
                Stream s = webRespon.GetResponseStream();
                StreamReader sr = new StreamReader(s);

                //读取服务器端返回的消息 
                String sReturnString = sr.ReadLine();
                s.Close();
                sr.Close();
                if (sReturnString == "Success")
                {
                    returnValue = 1;
                }
                else if (sReturnString == "Error")
                {
                    returnValue = 0;
                }

            }
            catch (Exception ex)
            {
                returnValue = 0;
            }
            finally
            {
                fs.Close();
                r.Close();
            }

            return returnValue;
        }
    }
}