C# HTTP系列11 以普通文件流方式上传文件远程服务器
应用程序中上传附件是最常使用的操作之一,ASP.NET客户端一般通过上传控件实现,
<input type="file" id="fileUpload" runat="server" />
后台C#使用以下方式将文件保存到服务上
HttpFileCollection files = HttpContext.Current.Request.Files;
HttpPostedFile postedFile = files["fileUpload"];
postedFile.SaveAs(postedFile.FileName);
上述的场景是简单的管理系统与网站中最常用的方式将客户端的文件上传到IIS服务器的指定目录下。
随着云端应用的发展与普及,第三方应用平台或者开发平台部署在云服务器上,例如阿里云、腾讯云、七牛云、青云等。第三方对外开放的应用平台大都是提供Restful API供开发者调用以上传(本地或者远端文件)或下载业务数据进行业务开发。
传统应用程序的上传控件方式在云端应用程序中针对附件上传与下载完全不适用。
下面提供一种通用的上传附件的方式:
/// <summary>
/// 将数据缓冲区(一般是指文件流或内存流对应的字节数组)上载到由 URI 标识的资源。(包含body数据)
/// </summary>
/// <param name="url">请求目标URL</param>
/// <param name="data">主体数据(字节数据)</param>
/// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
/// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取。默认为 application/octet-stream</param>
/// <returns>HTTP-POST的响应结果</returns>
public HttpResult UploadData(string url, byte[] data, string method = WebRequestMethods.Http.Post, string contentType = HttpContentType.APPLICATION_OCTET_STREAM)
{
HttpResult httpResult = new HttpResult();
HttpWebRequest httpWebRequest = null; try
{
httpWebRequest = WebRequest.Create(url) as HttpWebRequest;
httpWebRequest.Method = method;
httpWebRequest.Headers = HeaderCollection;
httpWebRequest.CookieContainer = CookieContainer;
httpWebRequest.ContentLength = data.Length;
httpWebRequest.ContentType = contentType;
httpWebRequest.UserAgent = _userAgent;
httpWebRequest.AllowAutoRedirect = _allowAutoRedirect;
httpWebRequest.ServicePoint.Expect100Continue = false; if (data != null)
{
httpWebRequest.AllowWriteStreamBuffering = true;
using (Stream requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(data, , data.Length);
requestStream.Flush();
}
} HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
if (httpWebResponse != null)
{
GetResponse(ref httpResult, httpWebResponse);
httpWebResponse.Close();
}
}
catch (WebException webException)
{
GetWebExceptionResponse(ref httpResult, webException);
}
catch (Exception ex)
{
GetExceptionResponse(ref httpResult, ex, method, contentType);
}
finally
{
if (httpWebRequest != null)
{
httpWebRequest.Abort();
}
} return httpResult;
}
借助该方法,又衍生出一下2中重载方式:
重载1:将指定的本地文件上载到具有指定的 URI 的资源。(包含body数据)
/// <summary>
/// 将指定的本地文件上载到具有指定的 URI 的资源。(包含body数据)
/// </summary>
/// <param name="url">请求目标URL</param>
/// <param name="fileFullName">待上传的文件(包含全路径的完全限定名)</param>
/// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
/// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取。默认为 application/octet-stream</param>
/// <returns>HTTP-POST的响应结果</returns>
public HttpResult UploadFile(string url, string fileFullName, string method = WebRequestMethods.Http.Post, string contentType = HttpContentType.APPLICATION_OCTET_STREAM)
{
HttpResult httpResult = new HttpResult();
if (!File.Exists(fileFullName))
{
httpResult.Status = HttpResult.STATUS_FAIL; httpResult.RefCode = (int)HttpStatusCode2.USER_FILE_NOT_EXISTS;
httpResult.RefText = HttpStatusCode2.USER_FILE_NOT_EXISTS.GetCustomAttributeDescription();
}
else
{
FileStream fileStream = new FileStream(fileFullName, FileMode.Open, FileAccess.Read);
byte[] data = fileStream.ToByteArray();
httpResult = UploadData(url, data, method, contentType);
} return httpResult;
}
重载2: 将指定的数据流对象(一般指文件流或内存流)上载到具有指定的 URI 的资源。(包含body数据)
/// <summary>
/// 将指定的数据流对象(一般指文件流或内存流)上载到具有指定的 URI 的资源。(包含body数据)
/// </summary>
/// <param name="url">请求目标URL</param>
/// <param name="stream">一般指文件流或内存流</param>
/// <param name="method">请求的方法。请使用 WebRequestMethods.Http 的枚举值</param>
/// <param name="contentType"><see langword="Content-type" /> HTTP 标头的值。请使用 ContentType 类的常量来获取。默认为 application/octet-stream</param>
/// <returns>HTTP-POST的响应结果</returns>
public HttpResult UploadStream(string url, Stream stream, string method = WebRequestMethods.Http.Post, string contentType = HttpContentType.APPLICATION_OCTET_STREAM)
{
HttpResult httpResult = new HttpResult();
if (stream == null)
{
httpResult.Status = HttpResult.STATUS_FAIL; httpResult.RefCode = (int)HttpStatusCode2.USER_STREAM_NULL;
httpResult.RefText = HttpStatusCode2.USER_STREAM_NULL.GetCustomAttributeDescription();
}
else
{
byte[] data = stream.ToByteArray();
httpResult = UploadData(url, data, method, contentType);
} return httpResult;
}
其中 UploadData() 调用了 GetResponse()、GetWebExceptionResponse()、GetExceptionResponse()方法
/// <summary>
/// 获取HTTP的响应信息
/// </summary>
/// <param name="httpResult">即将被HTTP请求封装函数返回的HttpResult变量</param>
/// <param name="httpWebResponse">正在被读取的HTTP响应</param>
private void GetResponse(ref HttpResult httpResult, HttpWebResponse httpWebResponse)
{
httpResult.HttpWebResponse = httpWebResponse;
httpResult.Status = HttpResult.STATUS_SUCCESS;
httpResult.StatusDescription = httpWebResponse.StatusDescription;
httpResult.StatusCode = (int)httpWebResponse.StatusCode; if (ReadMode == ResponseReadMode.Binary)
{
int len = (int)httpWebResponse.ContentLength;
httpResult.Data = new byte[len];
int bytesLeft = len;
int bytesRead = ; using (BinaryReader br = new BinaryReader(httpWebResponse.GetResponseStream()))
{
while (bytesLeft > )
{
bytesRead = br.Read(httpResult.Data, len - bytesLeft, bytesLeft);
bytesLeft -= bytesRead;
}
}
}
else
{
using (StreamReader sr = new StreamReader(httpWebResponse.GetResponseStream()))
{
httpResult.Text = sr.ReadToEnd();
}
}
}
/// <summary>
/// 获取HTTP访问网络期间发生错误时引发的异常响应信息
/// </summary>
/// <param name="httpResult">即将被HTTP请求封装函数返回的HttpResult变量</param>
/// <param name="webException">访问网络期间发生错误时引发的异常对象</param>
private void GetWebExceptionResponse(ref HttpResult httpResult, WebException webException)
{
HttpWebResponse exResponse = webException.Response as HttpWebResponse;
if (exResponse != null)
{
httpResult.HttpWebResponse = exResponse;
httpResult.Status = HttpResult.STATUS_FAIL;
httpResult.StatusDescription = exResponse.StatusDescription;
httpResult.StatusCode = (int)exResponse.StatusCode; httpResult.RefCode = httpResult.StatusCode;
using (StreamReader sr = new StreamReader(exResponse.GetResponseStream(), EncodingType))
{
httpResult.Text = sr.ReadToEnd();
httpResult.RefText = httpResult.Text;
} exResponse.Close();
}
}
/// <summary>
/// 获取HTTP的异常响应信息
/// </summary>
/// <param name="httpResult">即将被HTTP请求封装函数返回的HttpResult变量</param>
/// <param name="ex">异常对象</param>
/// <param name="method">HTTP请求的方式</param>
/// <param name="contentType">HTTP的标头类型</param>
private void GetExceptionResponse(ref HttpResult httpResult, Exception ex, string method, string contentType = "")
{
contentType = string.IsNullOrWhiteSpace(contentType) ? string.Empty : "-" + contentType;
StringBuilder sb = new StringBuilder();
sb.AppendFormat("[{0}] [{1}] [HTTP-" + method + contentType + "] Error: ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff"), _userAgent);
Exception exception = ex;
while (exception != null)
{
sb.AppendLine(exception.Message + " ");
exception = exception.InnerException;
}
sb.AppendLine(); httpResult.HttpWebResponse = null;
httpResult.Status = HttpResult.STATUS_FAIL; httpResult.RefCode = (int)HttpStatusCode2.USER_UNDEF;
httpResult.RefText += sb.ToString();
}
源码下载链接: https://pan.baidu.com/s/1bYh2COYxxeG1WIYJt6Wsnw 提取码: ysqd
C# HTTP系列11 以普通文件流方式上传文件远程服务器的更多相关文章
- ssh 下载文件以及上传文件到服务器
https://blog.csdn.net/jackghq/article/details/64124062 scp john@192.168.1.100:~/Desktop/MHN_error_so ...
- 将文件夹上传到FTP服务器,遍历上传,,,文件夹不能直接上传到FTP服务器上。。。
<? $ftp_ip = "FTP"; $ftp_user = "user"; $ftp_pwd = "password"; $con ...
- 异步上传文件,ajax上传文件,jQuery插件之ajaxFileUpload
http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html 一.ajaxFileUpload是一个异步上传文件的jQuery插件. ...
- Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包
1.UDP通信编解码类 (1) 类 # ------------------UDP通信解码编码类------------------------ from socket import * class ...
- models渲染字典&form表单上传文件&ajax上传文件
{# {% for u in teacher_d.keys %}#} {# {% for u in teacher_d.values %}#} {% for k,u in teacher_d.item ...
- C# 本地文件夹上传至网络服务器中(待续)
一.文件的上传参考 思想,C#FTP上传 /// <summary> /// 上传 /// </summary> /// <param name="filena ...
- 打包成apk,生成apk文件,上传到网站服务器提供链接下载
Android开发把项目打包成apk: 做完一个Android项目之后,如何才能把项目发布到Internet上供别人使用呢?我们需要将自己的程序打包成Android安装包文件--APK(Android ...
- 关于:基于http协议大文件断点续传上传至web服务器
关键部分 前端用file.slice()分块 前端用FileReader获取每一分块的md5值 后端用MultipartFile接受分块文件 后端用FileOutputStream拼装分块文件 话不多 ...
- asp.net (web)选择文件夹 上传文件
1 背景 用户本地有一份txt或者csv文件,无论是从业务数据库导出.还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工.挖掘和共创应用的时候,首先要将本地文件上传至ODPS,普通的小文件通 ...
随机推荐
- 成都,我们来啦 | Dubbo 社区开发者日
[关注 阿里巴巴云原生 公众号,回复关键词"报名",即可参与抽奖!] 活动时间:10 月 26 日 13:00 - 18:00 活动地点:成都市高新区交子大道中海国际中心 233 ...
- Nginx的相关问题
1.什么是Nginx的虚拟主机? 答:虚拟主机是一种特殊的软硬件技术,它可以将网络上的每一台计算机分成多个虚拟主机,每个虚拟主机可以独立对外提供www服务,这样就可以实现一台主机对外提供多个web服务 ...
- 使用SolrJ客户端管理SolrCloud(Solr集群)
1.使用SolrJ客户端管理SolrCloud(Solr集群). package com.taotao.search.service; import java.io.IOException; impo ...
- webpack4 plugins 篇
demo 代码点此,篇幅有限,仅介绍几个常用的. start 什么是 plugins ? While loaders are used to transform certain types of mo ...
- [TCP/IP] HTTPS的工作原理
一.首先HTTP请求服务端生成证书,客户端对证书的有效期.合法性.域名是否与请求的域名一致.证书的公钥(RSA加密)等进行校验: 二.客户端如果校验通过后,就根据证书的公钥的有效, 生成随机数,随机数 ...
- mysql-5..6.23-win64.zip安装及配置
MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行.但是官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的.很多人下了zip格式的解压发现没有setup.exe,面对一堆文件一头雾 ...
- Delphi-基础(运算符)
一.运算符 1.变量 2.运算符** 3.表达式 1.变量 变量解释:编程中最小的存储单元(空间),它的空间大小由它在声明时的数据类型决定. 1.1.声明 : 定义一个变量,告诉Delphi一个名字的 ...
- mysql数据库之用户管理和权限
mysql服务器进程在启动的时候会读取这6张表,并在内存中生成授权表,所以这几个文件是直接加载进内存的. 以后后续的任何用户登录及其访问权限的检查都通过检查这6张表来实现的.通过访问内存上所生成的结构 ...
- Windows Server2008 R2 服务器域名设置Https安全证书访问
域名支持Https访问设置 1.首先登陆域名申办公司的域名管理账号添加TXT域名解析信息 以新网域名公司为例:http://dcp.xinnet.com,输入域名:www.xxx.com和密码登录即可 ...
- JAVA的toString方法的一个小例子
Object是一个抽象类,他有很有方法,其中的toString方法是我们常见的一个方法,我们可以看这段代码 package com.com.day1; public class ToStringTes ...