• 使用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 + "--
    ";
          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 + "
    Content-Disposition: form-data; name="{0}"
    
    {1}
    ";
          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 = "
    ";
          string httpRow = "--" + boundary + "
    Content-Disposition: form-data; name="{0}"; filename="{1}"
    Content-Type: {2}
    
    ";
          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:	est.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#

  • 相关阅读:
    docker简单介绍----Dockerfile命令
    docker简单介绍----docker仓库的应用
    nginx实现https的配置文件
    docker简单介绍---网络端口管理
    mysql查看实时连接数
    linux 批量测试域名返回码脚本
    docker简单介绍----镜像和容器管理
    香冢
    GitHub 在使用命令行 git push 时报错:The requested URL returned error: 403
    守规矩应该被骂吗?
  • 原文地址:https://www.cnblogs.com/mvv118/p/4721175.html
Copyright © 2020-2023  润新知