使用WebClient上传文件并同时Post表单数据字段到服务端

之前遇到一个问题,就是使用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 = 0;
      int readLength = 0;
      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, 0, 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, 0);
      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, 0, 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 > 0)
{
  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[0].SaveAs(Path.Combine(filePath, HttpContext.Current.Request.Files[0].FileName));
  string filedValue = HttpContext.Current.Request.Form["key"];
}

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

时间: 2024-11-09 06:06:58

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

[C#]使用WebClient上传文件并同时Post表单数据字段到服务端

转自:http://www.97world.com/archives/2963 之前遇到一个问题,就是使用WebClient上传文件的同时,还要Post表单数据字段,一开始以为WebClient可以直接做到,结果发现如果先Post表单字段,就只能获取到字段及其值,如果先上传文件,也只能获取到上传文件的内容.测试了不少时间才发现WebClient不能这么使用. Google到相关的解决思路和类,因为发现网上的一些文章不是介绍得太简单就是太复杂,所以这里简单整理一下,既能帮助自己巩固知识,也希望能够

android 上传文件&quot;Content-Type&quot;,为&quot;application/octet-stream&quot; 用php程序在服务端用$GLOBALS[&#39;HTTP_RAW_POST_DATA&#39;]接受(二)

服务端php程序file_up.php function uploadFileBinary() { $this->initData(); $absoluteName = ""; $fid = ""; $handleWrite = null; if(!empty($GLOBALS['HTTP_RAW_POST_DATA']) && strlen($GLOBALS['HTTP_RAW_POST_DATA'])>0) { if(!empty($

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

最近在使用WebClient做一个客户端上传图片到IIS虚拟目录的程序的时候,遇到了一些问题,这里主要给出参考步骤分享给大家. 测试环境 服务器端:Windows Server 2003,IIS6.0. 上传文件的代码: using (WebClient client = new WebClient() { Credentials = CredentialCache.DefaultCredentials }) { client.UploadFile(uri, "PUT", file);

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

<script src="/static/js/jquery.js"></script><script> $("#reg-btn").click(function () { // 1. 取到用户填写的数据 var form_data_obj = new FormData(); form_data_obj.append('username',$('#id_username').val()); form_data_obj.append

WebClient 上传文件

MVC下 服务端代码: [HttpPost] public ActionResult UploadImg(string types) {string data = ""; try { if (types == "image") { foreach (string f in Request.Files.AllKeys) { string pathT = HttpRuntime.AppDomainAppPath.ToString() + "/UpLoadIma

WebClient和HttpWebRequest 上传文件

这几天对接淘宝的上传航司政策的接口.对期间出现的问题,以及使用WebClient和HttpWebReques 上传文件进行总结.本文重要信息已使用'*'代替 1.WebClient上传文件 使用UploadFile上传文件,其中fileNamePath为物理路径. public bool UpLoadFile(string fileNamePath,string url) { string timeStamp = DateTime.Now.ToString("YYYY-MM-DD HH:mm:s

使用webclient上传下载实例

转载:http://blog.csdn.net/kevonz/article/details/5078432 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net; using System.IO; namespace The9web.Com { class UpDownLoadFile {

Qt通过HTTP POST上传文件

本文使用Qt Creator用HTTP POST的方法上传文件,并给出一个上传文件的例程. 本文主要客户端,所以对于服务器端程序编写的描述会比较简略 服务器使用Django编写,django服务器接收文件的方法在文章http://www.cnblogs.com/fnng/p/3740274.html中有较为清晰的讲解,我搭建的服务器端程序除了没有网页客户端以及部分变量名称不同以外,基本上与这篇文章的服务器搭建过程一样. 如果服务器端程序发生变化,这篇文章后面给出的客户端例程可能就不再适用.因此如

PHP上传文件

//HTML页面 <form method="post" name="表单名" action="指定PHP文件或者方法"  enctype="multipart/form-data"  style="text-align:center"> <table style="text-align:center"border="1"class="fo