之前遇到一个问题,就是使用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. Centos部署nagios+apache实现服务器监控

    1.Nagios介绍 nagios是 一款功能强大的网络监视工具,它可以有效的监控windows.linux.unix主机状态以及路由器交换机的网络设置,打印机工作状态等,并将状态出 现异常的服务及时 ...

  2. CSS:表格样式(设置表格边框/文字/背景的样式)

    使用CSS能够制作出十分精美的表格. 代码整理自w3school:http://www.w3school.com.cn 效果图: 代码: <!DOCTYPE html PUBLIC " ...

  3. android131 360 05 手势触摸滑动,sim卡,开机启动的广播,手机联系人,SharedPreferences,拦截短信

    安卓手势触摸滑动: package com.itheima52.mobilesafe.activity; import android.app.Activity; import android.con ...

  4. Jordan Lecture Note-8: The Sequential Minimal Optimization Algorithm (SMO).

    The Sequential Minimal Optimization Algorithm (SMO) 本文主要介绍用于解决SVM对偶模型的算法,它于1998年由John Platt在论文“Seque ...

  5. 大型高性能ASP.NET系统架构设计

    大型动态应用系统平台主要是针对于大流量.高并发网站建立的底层系统架构.大型网站的运行需要一个可靠.安全.可扩展.易维护的应用系统平台做为支撑,以保证网站应用的平稳运行. 大型动态应用系统又可分为几个子 ...

  6. Socket之UDP分包组包

    一般传输大的文件和信息的时候需要涉及到分包和组包,方法有很多,下面一种是借鉴了别人的思路,供大家参考哈 分包 1.取出需要传输的文件和字符的长度和大小放入缓存区里面: 2.设定固定传输的长度,用需要传 ...

  7. mysql datetime、date、time、timestamp区别

    我们看看这几个数据库中(mysql.oracle和sqlserver)如何表示时间 mysql数据库:它们分别是 date.datetime.time.timestamp和year.date :“yy ...

  8. Pull Requests

    Contribution Guide Issue Tracker You can find outstanding issues on the GitHub Issue Tracker. Pull R ...

  9. 学习jQuery后的部分总结

    1.remove和empty <div id="div1"> <ul id="ul1"> <li>嘿嘿</li> ...

  10. fedora 23中配置nfs-server

    fedora 23中配置nfs-server */--> fedora 23中配置nfs-server Table of Contents 1. 产考资料 2. NFS配置文件 2.1. /et ...