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

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

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

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

HttpRequestClient类Code:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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
   }
}

客户端实例代码:

01
02
03
04
05
06
07
08
09
10
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);

服务端实例代码:

1
2
3
4
5
6
7
8
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" ];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值