应用程序中上传附件是最常使用的操作之一,ASP.NET客户端一般通过上传控件实现,

  1. <input type="file" id="fileUpload" runat="server" />

后台C#使用以下方式将文件保存到服务上

  1. HttpFileCollection files = HttpContext.Current.Request.Files;
  2. HttpPostedFile postedFile = files["fileUpload"];
  3. postedFile.SaveAs(postedFile.FileName);

上述的场景是简单的管理系统与网站中最常用的方式将客户端的文件上传到IIS服务器的指定目录下。

随着云端应用的发展与普及,第三方应用平台或者开发平台部署在云服务器上,例如阿里云、腾讯云、七牛云、青云等。第三方对外开放的应用平台大都是提供Restful API供开发者调用以上传(本地或者远端文件)或下载业务数据进行业务开发。

传统应用程序的上传控件方式在云端应用程序中针对附件上传与下载完全不适用。

下面提供一种通用的上传附件的方式:

  1. /// <summary>
  2. /// 将数据缓冲区(一般是指文件流或内存流对应的字节数组)上载到由 URI 标识的资源。(包含body数据)
  3. /// </summary>
  4. /// <param name="url">请求目标URL</param>
  5. /// <param name="data">主体数据(字节数据)</param>
  6. /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
  7. /// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取。默认为 application/octet-stream</param>
  8. /// <returns>HTTP-POST的响应结果</returns>
  9. public HttpResult UploadData(string url, byte[] data, string method = WebRequestMethods.Http.Post, string contentType = HttpContentType.APPLICATION_OCTET_STREAM)
  10. {
  11. HttpResult httpResult = new HttpResult();
  12. HttpWebRequest httpWebRequest = null;
  13.  
  14. try
  15. {
  16. httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
  17. httpWebRequest.Method = method;
  18. httpWebRequest.Headers = HeaderCollection;
  19. httpWebRequest.CookieContainer = CookieContainer;
  20. httpWebRequest.ContentLength = data.Length;
  21. httpWebRequest.ContentType = contentType;
  22. httpWebRequest.UserAgent = _userAgent;
  23. httpWebRequest.AllowAutoRedirect = _allowAutoRedirect;
  24. httpWebRequest.ServicePoint.Expect100Continue = false;
  25.  
  26. if (data != null)
  27. {
  28. httpWebRequest.AllowWriteStreamBuffering = true;
  29. using (Stream requestStream = httpWebRequest.GetRequestStream())
  30. {
  31. requestStream.Write(data, , data.Length);
  32. requestStream.Flush();
  33. }
  34. }
  35.  
  36. HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
  37. if (httpWebResponse != null)
  38. {
  39. GetResponse(ref httpResult, httpWebResponse);
  40. httpWebResponse.Close();
  41. }
  42. }
  43. catch (WebException webException)
  44. {
  45. GetWebExceptionResponse(ref httpResult, webException);
  46. }
  47. catch (Exception ex)
  48. {
  49. GetExceptionResponse(ref httpResult, ex, method, contentType);
  50. }
  51. finally
  52. {
  53. if (httpWebRequest != null)
  54. {
  55. httpWebRequest.Abort();
  56. }
  57. }
  58.  
  59. return httpResult;
  60. }

借助该方法,又衍生出一下2中重载方式:

重载1:将指定的本地文件上载到具有指定的 URI 的资源。(包含body数据)

  1. /// <summary>
  2. /// 将指定的本地文件上载到具有指定的 URI 的资源。(包含body数据)
  3. /// </summary>
  4. /// <param name="url">请求目标URL</param>
  5. /// <param name="fileFullName">待上传的文件(包含全路径的完全限定名)</param>
  6. /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
  7. /// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取。默认为 application/octet-stream</param>
  8. /// <returns>HTTP-POST的响应结果</returns>
  9. public HttpResult UploadFile(string url, string fileFullName, string method = WebRequestMethods.Http.Post, string contentType = HttpContentType.APPLICATION_OCTET_STREAM)
  10. {
  11. HttpResult httpResult = new HttpResult();
  12. if (!File.Exists(fileFullName))
  13. {
  14. httpResult.Status = HttpResult.STATUS_FAIL;
  15.  
  16. httpResult.RefCode = (int)HttpStatusCode2.USER_FILE_NOT_EXISTS;
  17. httpResult.RefText = HttpStatusCode2.USER_FILE_NOT_EXISTS.GetCustomAttributeDescription();
  18. }
  19. else
  20. {
  21. FileStream fileStream = new FileStream(fileFullName, FileMode.Open, FileAccess.Read);
  22. byte[] data = fileStream.ToByteArray();
  23. httpResult = UploadData(url, data, method, contentType);
  24. }
  25.  
  26. return httpResult;
  27. }

重载2: 将指定的数据流对象(一般指文件流或内存流)上载到具有指定的 URI 的资源。(包含body数据)

  1. /// <summary>
  2. /// 将指定的数据流对象(一般指文件流或内存流)上载到具有指定的 URI 的资源。(包含body数据)
  3. /// </summary>
  4. /// <param name="url">请求目标URL</param>
  5. /// <param name="stream">一般指文件流或内存流</param>
  6. /// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
  7. /// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取。默认为 application/octet-stream</param>
  8. /// <returns>HTTP-POST的响应结果</returns>
  9. public HttpResult UploadStream(string url, Stream stream, string method = WebRequestMethods.Http.Post, string contentType = HttpContentType.APPLICATION_OCTET_STREAM)
  10. {
  11. HttpResult httpResult = new HttpResult();
  12. if (stream == null)
  13. {
  14. httpResult.Status = HttpResult.STATUS_FAIL;
  15.  
  16. httpResult.RefCode = (int)HttpStatusCode2.USER_STREAM_NULL;
  17. httpResult.RefText = HttpStatusCode2.USER_STREAM_NULL.GetCustomAttributeDescription();
  18. }
  19. else
  20. {
  21. byte[] data = stream.ToByteArray();
  22. httpResult = UploadData(url, data, method, contentType);
  23. }
  24.  
  25. return httpResult;
  26. }

其中 UploadData() 调用了 GetResponse()、GetWebExceptionResponse()、GetExceptionResponse()方法

  1. /// <summary>
  2. /// 获取HTTP的响应信息
  3. /// </summary>
  4. /// <param name="httpResult">即将被HTTP请求封装函数返回的HttpResult变量</param>
  5. /// <param name="httpWebResponse">正在被读取的HTTP响应</param>
  6. private void GetResponse(ref HttpResult httpResult, HttpWebResponse httpWebResponse)
  7. {
  8. httpResult.HttpWebResponse = httpWebResponse;
  9. httpResult.Status = HttpResult.STATUS_SUCCESS;
  10. httpResult.StatusDescription = httpWebResponse.StatusDescription;
  11. httpResult.StatusCode = (int)httpWebResponse.StatusCode;
  12.  
  13. if (ReadMode == ResponseReadMode.Binary)
  14. {
  15. int len = (int)httpWebResponse.ContentLength;
  16. httpResult.Data = new byte[len];
  17. int bytesLeft = len;
  18. int bytesRead = ;
  19.  
  20. using (BinaryReader br = new BinaryReader(httpWebResponse.GetResponseStream()))
  21. {
  22. while (bytesLeft > )
  23. {
  24. bytesRead = br.Read(httpResult.Data, len - bytesLeft, bytesLeft);
  25. bytesLeft -= bytesRead;
  26. }
  27. }
  28. }
  29. else
  30. {
  31. using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
  32. {
  33. httpResult.Text = sr.ReadToEnd();
  34. }
  35. }
  36. }
  1. /// <summary>
  2. /// 获取HTTP访问网络期间发生错误时引发的异常响应信息
  3. /// </summary>
  4. /// <param name="httpResult">即将被HTTP请求封装函数返回的HttpResult变量</param>
  5. /// <param name="webException">访问网络期间发生错误时引发的异常对象</param>
  6. private void GetWebExceptionResponse(ref HttpResult httpResult, WebException webException)
  7. {
  8. HttpWebResponse exResponse = webException.Response as HttpWebResponse;
  9. if (exResponse != null)
  10. {
  11. httpResult.HttpWebResponse = exResponse;
  12. httpResult.Status = HttpResult.STATUS_FAIL;
  13. httpResult.StatusDescription = exResponse.StatusDescription;
  14. httpResult.StatusCode = (int)exResponse.StatusCode;
  15.  
  16. httpResult.RefCode = httpResult.StatusCode;
  17. using (StreamReader sr = new StreamReader(exResponse.GetResponseStream(), EncodingType))
  18. {
  19. httpResult.Text = sr.ReadToEnd();
  20. httpResult.RefText = httpResult.Text;
  21. }
  22.  
  23. exResponse.Close();
  24. }
  25. }
  1. /// <summary>
  2. /// 获取HTTP的异常响应信息
  3. /// </summary>
  4. /// <param name="httpResult">即将被HTTP请求封装函数返回的HttpResult变量</param>
  5. /// <param name="ex">异常对象</param>
  6. /// <param name="method">HTTP请求的方式</param>
  7. /// <param name="contentType">HTTP的标头类型</param>
  8. private void GetExceptionResponse(ref HttpResult httpResult, Exception ex, string method, string contentType = "")
  9. {
  10. contentType = string.IsNullOrWhiteSpace(contentType) ? string.Empty : "-" + contentType;
  11. StringBuilder sb = new StringBuilder();
  12. sb.AppendFormat("[{0}] [{1}] [HTTP-" + method + contentType + "] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), _userAgent);
  13. Exception exception = ex;
  14. while (exception != null)
  15. {
  16. sb.AppendLine(exception.Message + " ");
  17. exception = exception.InnerException;
  18. }
  19. sb.AppendLine();
  20.  
  21. httpResult.HttpWebResponse = null;
  22. httpResult.Status = HttpResult.STATUS_FAIL;
  23.  
  24. httpResult.RefCode = (int)HttpStatusCode2.USER_UNDEF;
  25. httpResult.RefText += sb.ToString();
  26. }

源码下载链接: https://pan.baidu.com/s/1bYh2COYxxeG1WIYJt6Wsnw 提取码: ysqd

C# HTTP系列11 以普通文件流方式上传文件远程服务器的更多相关文章

  1. ssh 下载文件以及上传文件到服务器

    https://blog.csdn.net/jackghq/article/details/64124062 scp john@192.168.1.100:~/Desktop/MHN_error_so ...

  2. 将文件夹上传到FTP服务器,遍历上传,,,文件夹不能直接上传到FTP服务器上。。。

    <? $ftp_ip = "FTP"; $ftp_user = "user"; $ftp_pwd = "password"; $con ...

  3. 异步上传文件,ajax上传文件,jQuery插件之ajaxFileUpload

    http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html 一.ajaxFileUpload是一个异步上传文件的jQuery插件. ...

  4. Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包

    1.UDP通信编解码类 (1) 类 # ------------------UDP通信解码编码类------------------------ from socket import * class ...

  5. models渲染字典&form表单上传文件&ajax上传文件

    {# {% for u in teacher_d.keys %}#} {# {% for u in teacher_d.values %}#} {% for k,u in teacher_d.item ...

  6. C# 本地文件夹上传至网络服务器中(待续)

    一.文件的上传参考 思想,C#FTP上传 /// <summary> /// 上传 /// </summary> /// <param name="filena ...

  7. 打包成apk,生成apk文件,上传到网站服务器提供链接下载

    Android开发把项目打包成apk: 做完一个Android项目之后,如何才能把项目发布到Internet上供别人使用呢?我们需要将自己的程序打包成Android安装包文件--APK(Android ...

  8. 关于:基于http协议大文件断点续传上传至web服务器

    关键部分 前端用file.slice()分块 前端用FileReader获取每一分块的md5值 后端用MultipartFile接受分块文件 后端用FileOutputStream拼装分块文件 话不多 ...

  9. asp.net (web)选择文件夹 上传文件

    1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...

随机推荐

  1. mysql启动报错:Failed to start LSB: start and stop MySQL

    报错信息: [root@youxx- bin]# service mysql status Redirecting to /bin/systemctl status mysql.service ¡ñ ...

  2. Vue动态修改网页标题

    业务需求,进入页面的时候,网页有个默认标题,加载的网页内容不同时,标题需要变更. 例:功能授权,功能授权(张三). Vue下有很多的方式去修改网页标题,这里总结下解决此问题的几种方案: 一.最笨方案 ...

  3. 2019-11-29-win10-uwp-列表模板选择器

    原文:2019-11-29-win10-uwp-列表模板选择器 title author date CreateTime categories win10 uwp 列表模板选择器 lindexi 20 ...

  4. LOOP AT GROUP语法练习

    DATA:P_MENGE TYPE EKKO-WKURS. DATA:P_MENGE1 TYPE EKKO-WKURS. SELECT * FROM EKKO INTO TABLE @DATA(LT_ ...

  5. 页面直接导出为PDF文件,支持分页与页边距

    将WEB页面直接导出为pdf文件是经常会用到的一个功能,尤其是各种报表系统.总结了一下目前几种主流的做法: 在后端用代码生成pdf文件,比如iText一类: 在后端抓取页面并生成pdf文件,比如pha ...

  6. c# 值类型和引用类型 笔记

    参考以下博文,我这里只是笔记一下,原文会更加详细 c#基础系列1---深入理解值类型和引用类型 堆栈和托管堆c# 值类型和引用类型 红色表示——“这啥?”(真实1个问题引出3个问题) CLR支持的两种 ...

  7. SpringCloud框架

    最近一直在针对SpringCloud框架做项目,从中踩了不少的坑,也渐渐梳理出了一些内容,由于SpringCloud作为一个全家桶,其中东西太多,所以这时候就要有所取舍,这里就想把自己比较常用组件及架 ...

  8. 【微信小程序】动态设置图片大小

    我们都知道微信小程序的组件image是用来显示图片的,它有一下几个属性:1.src              图片资源地址2.mode          图片裁剪.缩放的模式3.binderror   ...

  9. hadoop 完全分布式集群搭建

    1.在伪分布式基础上搭建,伪分布式搭建参见VM上Hadoop3.1伪分布式模式搭建 2.虚拟机准备,本次集群采用2.8.3版本与3.X版本差别不大,端口号所有差别 192.168.44.10 vmho ...

  10. 如何在unbuntu 16.04上在线安装vsftpd

    本文涉及命令如下: # service vsftpd status //查询vsftp服务状态 # apt-get remove vsftpd //卸载vsftpd # apt-get install ...