zoukankan      html  css  js  c++  java
  • C# HttpWebRequest 后台调用接口上传大文件以及其他参数

    直接上代码,包各位看客能用!!!

    1.首先请求参数的封装

    /// <summary>
        /// 上传文件 - 请求参数类
        /// </summary>
        public class UploadParameterType
        {
            public UploadParameterType()
            {
                FileNameKey = "fileName";
                Encoding = Encoding.UTF8;
                PostParameters = new Dictionary<string, string>();
            }
            /// <summary>
            /// 上传地址
            /// </summary>
            public string Url { get; set; }
            /// <summary>
            /// 文件名称key
            /// </summary>
            public string FileNameKey { get; set; }
            /// <summary>
            /// 文件名称value
            /// </summary>
            public string FileNameValue { get; set; }
            /// <summary>
            /// 编码格式
            /// </summary>
            public Encoding Encoding { get; set; }
            /// <summary>
            /// 上传文件的流
            /// </summary>
            public Stream UploadStream { get; set; }
            /// <summary>
            /// 上传文件 携带的参数集合
            /// </summary>
            public IDictionary<string, string> PostParameters { get; set; }
        }
    

      2.HttpWebRequest 封装

    /// <summary>
        /// Http上传文件类 - HttpWebRequest封装
        /// </summary>
        public class HttpUploadClient
        {
            /// <summary>
            /// 上传执行 方法
            /// </summary>
            /// <param name="parameter">上传文件请求参数</param>
            public static string Execute(UploadParameterType parameter)
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    // 1.分界线
                    string boundary = string.Format("----{0}", DateTime.Now.Ticks.ToString("x")),       // 分界线可以自定义参数
                        beginBoundary = string.Format("--{0}
    ", boundary),
                        endBoundary = string.Format("
    --{0}--
    ", boundary);
                    byte[] beginBoundaryBytes = parameter.Encoding.GetBytes(beginBoundary),
                        endBoundaryBytes = parameter.Encoding.GetBytes(endBoundary);
                    // 2.组装开始分界线数据体 到内存流中
                    memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length);
                    // 3.组装 上传文件附加携带的参数 到内存流中
                    if (parameter.PostParameters != null && parameter.PostParameters.Count > 0)
                    {
                        foreach (KeyValuePair<string, string> keyValuePair in parameter.PostParameters)
                        {
                            string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name="{0}"
    
    {1}
    {2}", keyValuePair.Key, keyValuePair.Value, beginBoundary);
                            byte[] parameterHeaderBytes = parameter.Encoding.GetBytes(parameterHeaderTemplate);
    
                            memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length);
                        }
                    }
                    // 4.组装文件头数据体 到内存流中
                    string fileHeaderTemplate = string.Format("Content-Disposition: form-data; name="{0}"; filename="{1}"
    Content-Type: application/octet-stream
    
    ", parameter.FileNameKey, parameter.FileNameValue);
                    byte[] fileHeaderBytes = parameter.Encoding.GetBytes(fileHeaderTemplate);
                    memoryStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);
                    // 5.组装文件流 到内存流中
                    byte[] buffer = new byte[1024 * 1024 * 1];
                    int size = parameter.UploadStream.Read(buffer, 0, buffer.Length);
                    while (size > 0)
                    {
                        memoryStream.Write(buffer, 0, size);
                        size = parameter.UploadStream.Read(buffer, 0, buffer.Length);
                    }
                    // 6.组装结束分界线数据体 到内存流中
                    memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                    // 7.获取二进制数据
                    byte[] postBytes = memoryStream.ToArray();
                    memoryStream.Close();
                    GC.Collect();
                    // 8.HttpWebRequest 组装
                    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(parameter.Url, UriKind.RelativeOrAbsolute));
                    webRequest.AllowWriteStreamBuffering = false;
                    webRequest.Method = "POST";
                    webRequest.Timeout = 1800000;
                    webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                    webRequest.ContentLength = postBytes.Length;
                    if (Regex.IsMatch(parameter.Url, "^https://"))
                    {
                        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                        ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                    }
                    // 9.写入上传请求数据
                    using (Stream requestStream = webRequest.GetRequestStream())
                    {
                        requestStream.Write(postBytes, 0, postBytes.Length);
                        requestStream.Close();
                    }
                    // 10.获取响应
                    using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                    {
                        using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), parameter.Encoding))
                        {
                            string body = reader.ReadToEnd();
                            reader.Close();
                            return body;
                        }
                    }
                }
            }
            /// <summary>
            /// 上传执行 方法
            /// </summary>
            /// <param name="parameter">上传文件请求参数</param>
            public static string Execute2(UploadParameterType parameter)
            {
                // 1.分界线
                string boundary = string.Format("----{0}", DateTime.Now.Ticks.ToString("x")),       // 分界线可以自定义参数
                    beginBoundary = string.Format("--{0}
    ", boundary),
                    endBoundary = string.Format("
    --{0}--
    ", boundary);
                byte[] beginBoundaryBytes = parameter.Encoding.GetBytes(beginBoundary),
                    endBoundaryBytes = parameter.Encoding.GetBytes(endBoundary);
                byte[] postBytes = new byte[] { };
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    // 2.组装开始分界线数据体 到内存流中
                    memoryStream.Write(beginBoundaryBytes, 0, beginBoundaryBytes.Length);
                    // 3.组装 上传文件附加携带的参数 到内存流中
                    if (parameter.PostParameters != null && parameter.PostParameters.Count > 0)
                    {
                        foreach (KeyValuePair<string, string> keyValuePair in parameter.PostParameters)
                        {
                            string parameterHeaderTemplate = string.Format("Content-Disposition: form-data; name="{0}"
    
    {1}
    {2}", keyValuePair.Key, keyValuePair.Value, beginBoundary);
                            byte[] parameterHeaderBytes = parameter.Encoding.GetBytes(parameterHeaderTemplate);
                            memoryStream.Write(parameterHeaderBytes, 0, parameterHeaderBytes.Length);
                        }
                    }
                    // 4.组装文件头数据体 到内存流中
                    string fileHeaderTemplate = string.Format("Content-Disposition: form-data; name="{0}"; filename="{1}"
    Content-Type: application/octet-stream
    
    ", parameter.FileNameKey, parameter.FileNameValue);
                    byte[] fileHeaderBytes = parameter.Encoding.GetBytes(fileHeaderTemplate);
                    memoryStream.Write(fileHeaderBytes, 0, fileHeaderBytes.Length);
    
                    // 5.组装结束分界线数据体 到内存流中
                    //memoryStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                    // 6.获取二进制数据
                    postBytes = memoryStream.ToArray();
                }
                // 7.HttpWebRequest 组装
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(new Uri(parameter.Url, UriKind.RelativeOrAbsolute));
                //对发送的数据不使用缓存【重要、关键】
                webRequest.AllowWriteStreamBuffering = false;
                webRequest.Method = "POST";
                webRequest.Timeout = 1800000;
                webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                webRequest.ContentLength = postBytes.Length + parameter.UploadStream.Length+endBoundaryBytes.Length;
                if (Regex.IsMatch(parameter.Url, "^https://"))
                {
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                    ServicePointManager.ServerCertificateValidationCallback = CheckValidationResult;
                }
                // 8.组装文件流
                byte[] buffer = new byte[1024 * 1024 * 1];
                int size = parameter.UploadStream.Read(buffer, 0, buffer.Length);
                Stream requestStream = webRequest.GetRequestStream();
                requestStream.Write(postBytes, 0, postBytes.Length);
                while (size > 0)
                {
                    requestStream.Write(buffer, 0, size);
                    size = parameter.UploadStream.Read(buffer, 0, buffer.Length);
                }
                requestStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
                requestStream.Close();
                // 9.获取响应
                using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(webResponse.GetResponseStream(), parameter.Encoding))
                    {
                        string body = reader.ReadToEnd();
                        reader.Close();
                        return body;
                    }
                }
            }
            static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
            {
                return true;
            }
    
    
        }
    

      HttpUploadClient类中两个Execute2,参考网上,大都用第一个,如果上传小文件没问题,要是比较大(百兆以上)就会内存溢出,然后就用流方式。思路是一样的

    3.调用示例:

                using (FileStream fs = new FileStream(@"C:\test.zip", FileMode.Open, FileAccess.Read))
                {
                    Dictionary<string, string> postParameter = new Dictionary<string, string>();
                    postParameter.Add("name", "heshang");
                    postParameter.Add("param", "1 2 3");
                    string result = HttpUploadClient.Execute(new UploadParameterType
                    {
                        Url = url,
                        UploadStream = fs,
                        FileNameValue = "test.zip",
                        PostParameters = postParameter
                    });
                }
    

      4.接口服务后台接受请求时:

    public IHttpActionResult Post()
            {
                HttpPostedFile file = HttpContext.Current.Request.Files[0];
                string pyPath = HttpContext.Current.Request["name"];
                string Params = HttpContext.Current.Request["params"];
                file.SaveAs("C:\test.zip");
                return Ok("");
            }
    

      5.完美解决大文件上传

  • 相关阅读:
    在Java当中如何优雅地处理临时文件
    lombok插件不建议使用的原因
    linux系统下修改tomcat的端口号时,需要修改的地方
    linux系统下报错为:直接在tomcat的bin目录下生成一个错误文件。
    Linux下修改tomcat端口号
    python实现断点续传下载文件
    Python中下划线---完全解读
    linux  指令 备注
    Linux下高并发socket最大连接数所受的各种限制
    python和pywin32实现窗口查找、遍历和点击
  • 原文地址:https://www.cnblogs.com/xibei/p/6123093.html
Copyright © 2011-2022 走看看