在基于Http协议的Post请求中,Content-type为application/x-www-form-urlencoded的传输只能传送非文件的数据。
如果想用Http的Post方法来上传数据及文件,需要实现Content-type为multipart/form-data类型的协议程序。
下面是参考了StackOverflow网站上的一个例子,实现了关于客户端上传文件的功能类,代码如下:
using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.IO;
namespace ZDWorks.ZDClock.Cloud
{
/// <summary>
/// 文件类型数据的内容参数
/// </summary>
public class FileParameter
{
// 文件内容
public byte[] File { get; set; }
// 文件名
public string FileName { get; set; }
// 文件内容类型
public string ContentType { get; set; }
public FileParameter(byte[] file) : this(file, null) { }
public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
public FileParameter(byte[] file, string filename, string contentType)
{
File = file;
FileName = filename;
ContentType = contentType;
}
}
/// <summary>
/// 数据与文件http请求
/// </summary>
public class HttpMultipartFormRequest
{
#region Data Members
private readonly Encoding DefaultEncoding = Encoding.UTF8;
private ResponseCallback m_Callback;
private byte[] m_FormData;
#endregion
#region Constructor
public HttpMultipartFormRequest()
{
}
#endregion
#region Delegate
public delegate void ResponseCallback(string msg);
#endregion
public void AsyncHttpRequest(string postUri, Dictionary<string, object> postParameters, ResponseCallback callback)
{
// 随机序列,用作防止服务器无法识别数据的起始位置
string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
// 设置contentType
string contentType = "multipart/form-data; boundary=" + formDataBoundary;
// 将数据转换为byte[]格式
m_FormData = GetMultipartFormData(postParameters, formDataBoundary);
// 回调函数
m_Callback = callback;
// 创建http对象
HttpWebRequest request = HttpWebRequest.CreateHttp(new Uri(postUri));
// 设为post请求
request.Method = "POST";
request.ContentType = contentType;
// 请求写入数据流
request.BeginGetRequestStream(GetRequestStreamCallback, request);
}
private void GetRequestStreamCallback(IAsyncResult ar)
{
HttpWebRequest request = ar.AsyncState as HttpWebRequest;
using (var postStream = request.EndGetRequestStream(ar))
{
postStream.Write(m_FormData, 0, m_FormData.Length);
postStream.Close();
}
request.BeginGetResponse(GetResponseCallback, request);
}
private void GetResponseCallback(IAsyncResult ar)
{
// 处理Post请求返回的消息
try
{
HttpWebRequest request = ar.AsyncState as HttpWebRequest;
HttpWebResponse response = request.EndGetResponse(ar) as HttpWebResponse;
using (var stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
string msg = reader.ReadToEnd();
if (m_Callback != null)
{
m_Callback(msg);
}
}
}
catch (Exception e)
{
string a = e.ToString();
if (m_Callback != null)
{
m_Callback(string.Empty);
}
}
}
private byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
{
Stream formDataStream = new MemoryStream();
bool needsCLRF = false;
foreach (var param in postParameters)
{
if (needsCLRF)
{
formDataStream.Write(DefaultEncoding.GetBytes("\r\n"), 0, DefaultEncoding.GetByteCount("\r\n"));
}
needsCLRF = true;
if (param.Value is FileParameter)
{
FileParameter fileToUpload = (FileParameter)param.Value;
string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n",
boundary,
param.Key,
fileToUpload.FileName ?? param.Key,
fileToUpload.ContentType ?? "application/octet-stream");
// 将与文件相关的header数据写到stream中
formDataStream.Write(DefaultEncoding.GetBytes(header), 0, DefaultEncoding.GetByteCount(header));
// 将文件数据直接写到stream中
formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
}
else
{
string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}",
boundary,
param.Key,
param.Value);
formDataStream.Write(DefaultEncoding.GetBytes(postData), 0, DefaultEncoding.GetByteCount(postData));
}
}
string tailEnd = "\r\n--" + boundary + "--\r\n";
formDataStream.Write(DefaultEncoding.GetBytes(tailEnd), 0, DefaultEncoding.GetByteCount(tailEnd));
// 将Stream数据转换为byte[]格式
formDataStream.Position = 0;
byte[] formData = new byte[formDataStream.Length];
formDataStream.Read(formData, 0, formData.Length);
formDataStream.Close();
return formData;
}
}
}
分享到:
相关推荐
客户端完全基于JavaScript的浏览器文件上传器,不需要任何浏览器插件,但需要和jQuery框架协同工作,支持超大文件上传,其算法是将一个超大文件切片成N个数据块依次提交给服务端处理,由服务端存储断点信息实现断点...
360云盘除了提供最基本的文件上传下载服务外,还提供文件实时同步备份功能,您只需将文件放到360云盘目录,360云盘程序将自动帮您上传这些文件至360云盘云存储服务中心,同时当您在其它电脑登录云盘时自动同步下载到...
360云盘除了提供最基本的文件上传下载服务外,还提供文件实时同步备份功能,您只需将文件放到360云盘目录,360云盘程序将自动帮您上传这些文件至360云盘云存储服务中心,同时当您在其它电脑登录云盘时自动同步下载到...
类似于Flashget操作,可以非常方便的实现windows向linux计算机上实现文件互传。主要是Linux端不要复杂的设置。同时支持SCP协议。它的主要功能就是在本地与远程计算机间安全的复制文件。 特性: 图形用户界面 多语言...
RewriteCond %{HTTP_USER_AGENT} "android|blackberry|googlebot-mobile|iemobile|ipad|iphone|ipod|opera mobile|palmos|webos|UCBrowser|QQBrowser|wap|Nokia|Lumia|Windows Phone|Windows 10 Mobile|Windows ...
7个目标文件 摘要:Java源码,初学实例,EJB调用实例 各种EJB之间的调用源码示例,用远程接口的引用访问EJB、函数将被FirstEJB调用,同时它将调用secondEJB 基于JAVA的UDP服务器模型源代码 2个目标文件 摘要:Java...
微软推出的Windows Phone平台是微软在移动互联网时代的一个重量级产品,微软对于WindowsPhone7的推广力度非常大,因此很多公司也开始进行Windows Phone7产品的研发,2011年下半年Windows Phone7开发人员的需求将会...
凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码) 15个目标文件 摘要:Java源码,初学实例,基于EJB的真实...
WebUploader 文件上传 font-wesome/icomoon.io 字体/图标 支持浏览器 前台 ie6 后台 chrome/firefox/ie9 github地址:https://github.com/dongfangshangren/Zblog。 示例见:...
实现App封装,混合开发App,100多JS接口功能交互。 2、制作小程序 通过接口网站封装成小程序。 安装环境变色龙app封装系统源码 环境:PHP 5.6 MySQL 存储:七牛存储 源码介绍: 这款变色龙app封装系统源码更...
25.文件上传格式过滤(1.04新增)。 更新历史: 1.01 修正对12月份的日期验证(感谢 flylg999 ) 1.03 修正Range验证类型时将数字当字符串比较的bug(感谢 cncom 和 xtlhnhbb ) 修正日期验证(感谢 Papsam ) 增加...
� 良好的盈利模式( 3/7 开),产业链条的各方:运营商、制造商、独立软件生产商都可以获得不错的利 益 。 将移动终端的评价标准从硬件向软件转变,极大的激发了软件开发者的热情。 � Android 的源代码遵循 Apache...
仅支持windows平台,Python3.6+ 和 Chrome浏览器 安装依赖包 ``` pip3 install -r requirements.txt ``` ## 用法 1. 修改config.ini文件,保存你的配置信息 ``` ;修改说明: ;[信息] ;privilege_val 将“特权码”...
安装包不需要上传到App Store也能被安装 (开发调试 企业灰度) 防止证书权限滥用:设备限制、指定APP、iCloud/PUSH/后台运行等附加权限控制 苹果的解决方案:双层代码签名+描述文件: 这里画一张图附上: 在iOS...