.net用multipart/form-data协议post上传文件
1、先封装一个MsMultiPartFormData类,用于封装上传的对象
public class MsMultiPartFormData
{
private List<byte> formData;
public String Boundary = "---------------"+DateTime.Now.Ticks.ToString("x");
private String fieldName = "Content-Disposition: form-data; name=\"{0}\"";
private String fileContentType = "Content-Type: {0}";
private String fileField = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"";
private Encoding encode = Encoding.GetEncoding("UTF-8");
public MsMultiPartFormData()
{
formData = new List<byte>();
}
public void AddFormField(String FieldName, String FieldValue)
{
String newFieldName = fieldName;
newFieldName = string.Format(newFieldName, FieldName);
formData.AddRange(encode.GetBytes("--" + Boundary + "\r\n"));
formData.AddRange(encode.GetBytes(newFieldName + "\r\n\r\n"));
formData.AddRange(encode.GetBytes(FieldValue + "\r\n"));
}
public void AddFile(String FieldName, String FileName, byte[] FileContent, String ContentType)
{
String newFileField = fileField;
String newFileContentType = fileContentType;
newFileField = string.Format(newFileField, FieldName, FileName);
newFileContentType = string.Format(newFileContentType, ContentType);
formData.AddRange(encode.GetBytes("--" + Boundary + "\r\n"));
formData.AddRange(encode.GetBytes(newFileField + "\r\n"));
formData.AddRange(encode.GetBytes(newFileContentType + "\r\n\r\n"));
formData.AddRange(FileContent);
formData.AddRange(encode.GetBytes("\r\n"));
}
public void AddStreamFile(String FieldName, String FileName, byte[] FileContent)
{
AddFile(FieldName, FileName, FileContent, "application/octet-stream");
}
public void PrepareFormData()
{
formData.AddRange(encode.GetBytes("--" + Boundary + "--"));
}
public List<byte> GetFormData()
{
return formData;
}
}
再封装一个http的post请求
public static class PostDataServer
{
public static string HttpPostData(string url,MsMultiPartFormData form,string filePath,string fileKeyName="file",int timeOut=360000)
{
string result = "";
WebRequest request = WebRequest.Create(url);
request.Timeout = timeOut;
FileStream file = new FileStream(filePath, FileMode.Open);
byte[] bb = new byte[file.Length];
file.Read(bb, 0, (int)file.Length);
file.Close();
string fileName = Path.GetFileName(filePath);
form.AddStreamFile(fileKeyName, fileName, bb);
form.PrepareFormData();
request.ContentType = "multipart/form-data; boundary=" + form.Boundary;
request.Method = "POST";
Stream stream = request.GetRequestStream();
foreach (var b in form.GetFormData())
{
stream.WriteByte(b);
}
stream.Close();
WebResponse response = request.GetResponse();
using (var httpStreamReader = new StreamReader(response.GetResponseStream(),Encoding.GetEncoding("utf-8")))
{
result = httpStreamReader.ReadToEnd();
}
response.Close();
request.Abort();
return result;
}
}
2、为避免上传文件时跨域,所以网站创建一个一般处理程序来先上传文件到自己的网站,再上传到需要上传的服务器,新建SendFileHandler.ashx,主要代码:
public class SendFileHandler : IHttpHandler
{
/// <summary>
/// 存放文件的物理根路径
/// </summary>
string RootFolder = "files";
string UPLOADFILE_SERVICE_URL="http://.....";//最终接收文件上传的服务接口
public void ProcessRequest(HttpContext context)
{
object result = null;
string temSavePath = context.Server.MapPath(@"~\") + RootFolder;
if (!Directory.Exists(temSavePath))
{
Directory.CreateDirectory(temSavePath);
}
if (context.Request.Files != null && context.Request.Files.Count > 0)
{
HttpPostedFile file = context.Request.Files[0];
string saveFileName = String.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddhhmmssffff"), Path.GetExtension(file.FileName));//保存文件名称
string fileName = String.Format(@"{0}\{1}", temSavePath, saveFileName);
file.SaveAs(fileName);
MsMultiPartFormData form = new MsMultiPartFormData();
string decodeName = HttpUtility.UrlDecode(Path.GetFileName(fileName));//最终服务器会按原文件名保存文件,所以需要将文件名编码下,防止中文乱码
string rst = PostDataServer.HttpPostData(UPLOADFILE_SERVICE_URL, form, fileName, decodeName);
context.Response.Write(rst);//输出上传文件返回结果
context.Response.End();
}