之前遇到一个问题,就是使用WebClient上传文件的同时,还要Post表单数据字段,一开始以为WebClient可以直接做到,结果发现如果先 Post表单字段,就只能获取到字段及其值,如果先上传文件,也只能获取到上传文件的内容。测试了不少时间才发现WebClient不能这么使用。

Google到相关的解决思路和类,因为发现网上的一些文章不是介绍得太简单就是太复杂,所以这里简单整理一下,既能帮助自己巩固知识,也希望能够帮到大家!如果大家有什么不明白,可以直接留言问我。

关于WebClient上传文件并同时Post表单数据的实现原理,大家可以参考这篇文章http://www.cnblogs.com /goody9807/archive/2007/06/06/773735.html,介绍得非常详细,但是类和实例有些模糊,所以类和实例可以直接参 考本文。

HttpRequestClient类Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Net; namespace Common.Helper
{
/// <summary>
/// description:http post请求客户端
/// last-modified-date:2012-02-28
/// </summary>
public class HttpRequestClient
{
#region //字段
private ArrayList bytesArray;
private Encoding encoding = Encoding.UTF8;
private string boundary = String.Empty;
#endregion #region //构造方法
public HttpRequestClient()
{
bytesArray = new ArrayList();
string flag = DateTime.Now.Ticks.ToString("x");
boundary = "---------------------------" + flag;
}
#endregion #region //方法
/// <summary>
/// 合并请求数据
/// </summary>
/// <returns></returns>
private byte[] MergeContent()
{
int length = ;
int readLength = ;
string endBoundary = "--" + boundary + "--\r\n";
byte[] endBoundaryBytes = encoding.GetBytes(endBoundary); bytesArray.Add(endBoundaryBytes); foreach (byte[] b in bytesArray)
{
length += b.Length;
} byte[] bytes = new byte[length]; foreach (byte[] b in bytesArray)
{
b.CopyTo(bytes, readLength);
readLength += b.Length;
} return bytes;
} /// <summary>
/// 上传
/// </summary>
/// <param name="requestUrl">请求url</param>
/// <param name="responseText">响应</param>
/// <returns></returns>
public bool Upload(String requestUrl, out String responseText)
{
WebClient webClient = new WebClient();
webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary); byte[] responseBytes;
byte[] bytes = MergeContent(); try
{
responseBytes = webClient.UploadData(requestUrl, bytes);
responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
return true;
}
catch (WebException ex)
{
Stream responseStream = ex.Response.GetResponseStream();
responseBytes = new byte[ex.Response.ContentLength];
responseStream.Read(responseBytes, , responseBytes.Length);
}
responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
return false;
} /// <summary>
/// 设置表单数据字段
/// </summary>
/// <param name="fieldName">字段名</param>
/// <param name="fieldValue">字段值</param>
/// <returns></returns>
public void SetFieldValue(String fieldName, String fieldValue)
{
string httpRow = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n";
string httpRowData = String.Format(httpRow, fieldName, fieldValue); bytesArray.Add(encoding.GetBytes(httpRowData));
} /// <summary>
/// 设置表单文件数据
/// </summary>
/// <param name="fieldName">字段名</param>
/// <param name="filename">字段值</param>
/// <param name="contentType">内容内型</param>
/// <param name="fileBytes">文件字节流</param>
/// <returns></returns>
public void SetFieldValue(String fieldName, String filename, String contentType, Byte[] fileBytes)
{
string end = "\r\n";
string httpRow = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string httpRowData = String.Format(httpRow, fieldName, filename, contentType); byte[] headerBytes = encoding.GetBytes(httpRowData);
byte[] endBytes = encoding.GetBytes(end);
byte[] fileDataBytes = new byte[headerBytes.Length + fileBytes.Length + endBytes.Length]; headerBytes.CopyTo(fileDataBytes, );
fileBytes.CopyTo(fileDataBytes, headerBytes.Length);
endBytes.CopyTo(fileDataBytes, headerBytes.Length + fileBytes.Length); bytesArray.Add(fileDataBytes);
}
#endregion
}
}
客户端实例代码:
string fileFullName=@"c:\test.txt",filedValue="hello_world",responseText = "";
FileStream fs = new FileStream(fileFullName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
byte[] fileBytes = new byte[fs.Length];
fs.Read(fileBytes, , fileBytes.Length);
fs.Close(); fs.Dispose(); HttpRequestClient httpRequestClient = new HttpRequestClient();
httpRequestClient.SetFieldValue("key", filedValue);
httpRequestClient.SetFieldValue("uploadfile", Path.GetFileName(fileFullName), "application/octet-stream", fileBytes);
httpRequestClient.Upload(NormalBotConfig.Instance.GetUploadFileUrl(), out responseText);
服务端实例代码:
if (HttpContext.Current.Request.Files.AllKeys.Length > )
{
string filePath = Path.Combine(HttpContext.Current.Server.MapPath("~/"), "UploadFile", DateTime.Now.Year.ToString(), DateTime.Now.Month.ToString(), DateTime.Now.Day.ToString());
if (!Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
//这里我直接用索引来获取第一个文件,如果上传了多个文件,可以通过遍历HttpContext.Current.Request.Files.AllKeys取“key值”,再通过HttpContext.Current.Request.Files[“key值”]获取文件
HttpContext.Current.Request.Files[].SaveAs(Path.Combine(filePath, HttpContext.Current.Request.Files[].FileName));
string filedValue = HttpContext.Current.Request.Form["key"];
}

转:http://www.97world.com/archives/2963#

使用WebClient上传文件并同时Post表单数据字段到服务端的更多相关文章

  1. android 上传文件"Content-Type",为"application/octet-stream" 用php程序在服务端用$GLOBALS['HTTP_RAW_POST_DATA']接受(二)

    服务端php程序file_up.php function uploadFileBinary() { $this->initData(); $absoluteName = "" ...

  2. 使用WebClient上传文件时的一些问题

    最近在使用WebClient做一个客户端上传图片到IIS虚拟目录的程序的时候,遇到了一些问题,这里主要给出参考步骤分享给大家. 测试环境 服务器端:Windows Server 2003,IIS6.0 ...

  3. WebClient 上传文件

    iis6.0 条件:必须启用WEBDAV  需要将要上传到的目录权限加上匿名登陆,而且必须在IIS上创建虚拟目录,将文件上传到虚拟目录才能成功,否则就会出现403禁止错误下面放上我测试好的代码. // ...

  4. WebClient 上传文件 上传文件到服务器端

    一直对于上传文件到服务器端困惑:以前,现在,学到了关于WebClient的post知识 瞬间对于上传文件到服务器觉得好轻松: 原理很简单:我们通过post服务器的页面:把本地的文件直接传递过去: 现在 ...

  5. JSP SMARTUPLOAD组件:上传文件时同时获取表单参数

    原因很简单: 注意更改from 属性啊!否则为null! 因为你用jspsmartuploadsmart时post请求 的格式是multipart/form-data,即enctype="m ...

  6. 关于php上传文件过大的表单回填

    也许标题有点绕口,有点无法让人理解.请原谅博主,语文学的不好,都赖体育老师. 问题场景重现:在某次迭代中,接到这样一个需求:当新建或编辑一个Bug(包含附件以及其他字段)上传附件过大时,退回到编辑页面 ...

  7. ajax上传文件 基于jquery form表单上传文件

    <script src="/static/js/jquery.js"></script><script> $("#reg-btn&qu ...

  8. C# WebClient进行FTP服务上传文件和下载文件

    定义WebClient使用的操作类: 操作类名称WebUpDown WebClient上传文件至Ftp服务: //// <summary> /// WebClient上传文件至Ftp服务 ...

  9. webclient上传下载文件

    定义WebClient使用的操作类: 操作类名称WebUpDown WebClient上传文件至Ftp服务: //// <summary> /// WebClient上传文件至Ftp服务 ...

随机推荐

  1. android4.4短信新概念

    android4.4对短信引入了一个全新的概念:默认短信应用.即android用户可以在系统设置里面选择一个默认的短信应用,只有这个应用才能进行手机的基本短信操作.按照google自己的解释这样做的原 ...

  2. 句柄(Handle)

    1.句柄是什么?    在windows中,句柄是和对象一一对应的32位无符号整数值.对象可以映射到唯一的句柄,句柄也可以映射到唯一的对象.2.为什么我们需要句柄?     更准确地说,是window ...

  3. [018]C++ explicit构造函数

    explicit [英][ɪkˈsplɪsɪt][美][ɪkˈsplɪsɪt] adj.明确的,清楚的; 直言的; 详述的; 不隐瞒的; 看到上面的英文解释,我们应该就知道explicit构造函数是什 ...

  4. PAT 1015

    1015. Reversible Primes (20) A reversible prime in any number system is a prime whose "reverse& ...

  5. Android ADB启动失败 ADB server out of date

    调试Android程序时总提示ADB未运行,转到命令行方式下启动ADB, adb kille-server停止ADB, 然后再运行adb start-server 随后提示: adb server i ...

  6. 优化sql,返回行数少情况下,NL比hash快好多

    sql如下 select t.id, t.value, tt.sort as sortno from ENGINEERING_TYPE t left join ENGINEERING_TYPE tt ...

  7. WIndows 7 与 Debian 7 双系统启动引导

    以前写有一篇文章是Windows XP下引导Linux的(http://www.cnblogs.com/ibgo/archive/2012/05/20/2510736.html),采用的是grub4d ...

  8. Windows环境下使用Apache+mod_wsgi部署webpy

    1.安装Python和Apache. 2.安装mod_wsgi后获得wsgi.so,并将wsgi.so放到Apache的modules文件夹下. 3.安装webpy. 4.打开httpd.conf(在 ...

  9. 详细讲解Android对自己的应用代码进行混淆加密防止反编译

    1.查看项目中有没有proguard.cfg. 2.如果没有那就看看这个文件中写的什么吧,看完后将他复制到你的项目中. -optimizationpasses 5 -dontusemixedcasec ...

  10. Xilinx 网站资源导读2

    Xilinx 网站资源导读 ———版权声明———–本文作者 Ricky Suwww.fpganotes.comrickysu.fpga@gmail.com 欢迎转载,转载请保持原样及署名商业使用须得到 ...