zoukankan      html  css  js  c++  java
  • c# 模拟表单提交,post form 上传文件、数据内容

    转自:https://www.cnblogs.com/DoNetCShap/p/10696277.html

    表单提交协议规定:
    要先将 HTTP 要求的 Content-Type 设为 multipart/form-data,而且要设定一个 boundary 参数,
    这个参数是由应用程序自行产生,它会用来识别每一份资料的边界 (boundary),
    用以产生多重信息部份 (message part)。
    而 HTTP 服务器可以抓取 HTTP POST 的信息,


    基本内容:
    1. 每个信息部份都要用 --[BOUNDARY_NAME] 来包装,以分隔出信息的每个部份,而最后要再加上一个 --[BOUNDARY_NAME] 来表示结束。
    2. 每个信息部份都要有一个 Content-Disposition: form-data; name="",而 name 设定的就是 HTTP POST 的键值 (key)。
    3. 声明区和值区中间要隔两个新行符号( )。
    4. 中间可以夹入二进制资料,但二进制资料必须要格式化为二进制字符串。
    5. 若要设定不同信息段的资料型别 (Content-Type),则要在信息段内的声明区设定。


    两个form内容模板
    boundary = "----" + DateTime.Now.Ticks.ToString("x");//程序生成
    1.文本内容
    " --" + boundary +
    " Content-Disposition: form-data; name="键"; filename="文件名"" +
    " Content-Type: application/octet-stream" +
    " ";
    2.文件内容
    " --" + boundary +
    " Content-Disposition: form-data; name="键"" +
    " 内容";

     1 /// <summary>
     2 /// 表单数据项
     3 /// </summary>
     4 public class FormItemModel
     5 {
     6     /// <summary>
     7     /// 表单键,request["key"]
     8     /// </summary>
     9     public string Key { set; get; }
    10     /// <summary>
    11     /// 表单值,上传文件时忽略,request["key"].value
    12     /// </summary>
    13     public string Value { set; get; }
    14     /// <summary>
    15     /// 是否是文件
    16     /// </summary>
    17     public bool IsFile
    18     {
    19         get
    20         {
    21             if (FileContent==null || FileContent.Length == 0)
    22                 return false;
    23  
    24             if (FileContent != null && FileContent.Length > 0 && string.IsNullOrWhiteSpace(FileName))
    25                 throw new Exception("上传文件时 FileName 属性值不能为空");
    26             return true;
    27         }
    28     }
    29     /// <summary>
    30     /// 上传的文件名
    31     /// </summary>
    32     public string FileName { set; get; }
    33     /// <summary>
    34     /// 上传的文件内容
    35     /// </summary>
    36     public Stream FileContent { set; get; }
    37 }
      1 /// <summary>
      2 /// 使用Post方法获取字符串结果
      3 /// </summary>
      4 /// <param name="url"></param>
      5 /// <param name="formItems">Post表单内容</param>
      6 /// <param name="cookieContainer"></param>
      7 /// <param name="timeOut">默认20秒</param>
      8 /// <param name="encoding">响应内容的编码类型(默认utf-8)</param>
      9 /// <returns></returns>
     10 public static string PostForm(string url, List<FormItemModel> formItems, CookieContainer cookieContainer = null, string refererUrl = null, Encoding encoding = null,int timeOut = 20000)
     11 {
     12     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
     13     #region 初始化请求对象
     14     request.Method = "POST";
     15     request.Timeout = timeOut;
     16     request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
     17     request.KeepAlive = true;
     18     request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
     19     if (!string.IsNullOrEmpty(refererUrl))
     20         request.Referer = refererUrl;
     21     if (cookieContainer != null)
     22         request.CookieContainer = cookieContainer;
     23     #endregion
     24  
     25     string boundary = "----" + DateTime.Now.Ticks.ToString("x");//分隔符
     26     request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
     27     //请求流
     28     var postStream = new MemoryStream();
     29     #region 处理Form表单请求内容
     30     //是否用Form上传文件
     31     var formUploadFile = formItems != null && formItems.Count > 0;
     32     if (formUploadFile)
     33     {
     34         //文件数据模板
     35         string fileFormdataTemplate =
     36             "
    --" + boundary +
     37             "
    Content-Disposition: form-data; name="{0}"; filename="{1}"" +
     38             "
    Content-Type: application/octet-stream" +
     39             "
    
    ";
     40         //文本数据模板
     41         string dataFormdataTemplate =
     42             "
    --" + boundary +
     43             "
    Content-Disposition: form-data; name="{0}"" +
     44             "
    
    {1}";
     45         foreach (var item in formItems)
     46         {
     47             string formdata = null;
     48             if (item.IsFile)
     49             {
     50                 //上传文件
     51                 formdata = string.Format(
     52                     fileFormdataTemplate,
     53                     item.Key, //表单键
     54                     item.FileName);
     55             }
     56             else
     57             {
     58                 //上传文本
     59                 formdata = string.Format(
     60                     dataFormdataTemplate,
     61                     item.Key,
     62                     item.Value);
     63             }
     64  
     65             //统一处理
     66             byte[] formdataBytes = null;
     67             //第一行不需要换行
     68             if (postStream.Length == 0)
     69                 formdataBytes = Encoding.UTF8.GetBytes(formdata.Substring(2, formdata.Length - 2));
     70             else
     71                 formdataBytes = Encoding.UTF8.GetBytes(formdata);
     72             postStream.Write(formdataBytes, 0, formdataBytes.Length);
     73  
     74             //写入文件内容
     75             if (item.FileContent != null && item.FileContent.Length>0)
     76             {
     77                 using (var stream = item.FileContent)
     78                 {
     79                     byte[] buffer = new byte[1024];
     80                     int bytesRead = 0;
     81                     while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
     82                     {
     83                         postStream.Write(buffer, 0, bytesRead);
     84                     }
     85                 }
     86             }
     87         }
     88         //结尾
     89         var footer = Encoding.UTF8.GetBytes("
    --" + boundary + "--
    ");
     90         postStream.Write(footer, 0, footer.Length);
     91  
     92     }
     93     else
     94     {
     95         request.ContentType = "application/x-www-form-urlencoded";
     96     }
     97     #endregion
     98  
     99     request.ContentLength = postStream.Length;
    100  
    101     #region 输入二进制流
    102     if (postStream != null)
    103     {
    104         postStream.Position = 0;
    105         //直接写入流
    106         Stream requestStream = request.GetRequestStream();
    107  
    108         byte[] buffer = new byte[1024];
    109         int bytesRead = 0;
    110         while ((bytesRead = postStream.Read(buffer, 0, buffer.Length)) != 0)
    111         {
    112             requestStream.Write(buffer, 0, bytesRead);
    113         }
    114  
    115         ////debug
    116         //postStream.Seek(0, SeekOrigin.Begin);
    117         //StreamReader sr = new StreamReader(postStream);
    118         //var postStr = sr.ReadToEnd();
    119         postStream.Close();//关闭文件访问
    120     }
    121     #endregion
    122  
    123     HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    124     if (cookieContainer != null)
    125     {
    126         response.Cookies = cookieContainer.GetCookies(response.ResponseUri);
    127     }
    128  
    129     using (Stream responseStream = response.GetResponseStream())
    130     {
    131         using (StreamReader myStreamReader = new StreamReader(responseStream, encoding ?? Encoding.UTF8))
    132         {
    133             string retString = myStreamReader.ReadToEnd();
    134             return retString;
    135         }
    136     }
    137 }

    运行方式:

     1 var url = "http://127.0.0.1/testformdata.aspx?aa=1&bb=2&ccc=3";
     2 var log1=@"D:	emplog1.txt";
     3 var log2 = @"D:	emplog2.txt";
     4 var formDatas = new List<Grass.Net.FormItemModel>();
     5 //添加文件
     6 formDatas.Add(new Grass.Net.FormItemModel()
     7 {
     8     Key="log1",
     9     Value="",
    10     FileName = "log1.txt",
    11     FileContent=File.OpenRead(log1)
    12 });
    13 formDatas.Add(new Grass.Net.FormItemModel()
    14 {
    15     Key = "log2",
    16     Value = "",
    17     FileName = "log2.txt",
    18     FileContent = File.OpenRead(log2)
    19 });
    20 //添加文本
    21 formDatas.Add(new Grass.Net.FormItemModel()
    22 {
    23     Key = "id",
    24     Value = "id-test-id-test-id-test-id-test-id-test-"
    25 });
    26 formDatas.Add(new Grass.Net.FormItemModel()
    27 {
    28     Key = "name",
    29     Value = "name-test-name-test-name-test-name-test-name-test-"
    30 });
    31 //提交表单
    32 var result = PostForm(url, formDatas);

    以下内容做了一些优化修改:

     1 if (formUploadFile)
     2     {
     3         //文件数据模板
     4         string fileFormdataTemplate =
     5             "
    --" + boundary +
     6             "
    Content-Disposition: form-data; name="{0}"; filename="{1}"" +
     7             "
    Content-Type: application/octet-stream" +
     8             "
    
    ";
     9         //文本数据模板
    10         string dataFormdataTemplate =
    11             "
    --" + boundary +
    12             "
    Content-Disposition: form-data; name="{0}"" +
    13             "
    
    {1}";
    14         //头部
    15         var header = Encoding.UTF8.GetBytes("--" + boundary);
    16         postStream.Write(header, 0, header.Length);
    17         var index = 0;
    18         foreach (var item in formItems)
    19         {
    20             index++;
    21             string formdata = null;
    22             if (item.IsFile)
    23             {
    24                 if (index == 1)
    25                 {
    26                     formdata = string.Format("
    Content-Disposition: form-data; name="{0}"; filename="{1}"
    Content-Type: application/octet-stream
    
    ", item.Key, item.FileName);
    27  
    28                 }
    29                 else
    30                 {
    31                     //上传文件
    32                     formdata = string.Format(fileFormdataTemplate,item.Key,item.FileName);
    33  
    34                 }
    35         
    36             }
    37             else
    38             {
    39                 if (index==1)
    40                 {
    41                     formdata = string.Format("
    Content-Disposition: form-data; name="{0}"
    
    {1}", item.Key, item.FileName);
    42                 }
    43                 else
    44                 {
    45                     //上传文本
    46                     formdata = string.Format(dataFormdataTemplate, item.Key, item.Value);
    47                 }
    48                  
    49             }
    50  
    51             //统一处理
    52             byte[] formdataBytes = Encoding.UTF8.GetBytes(formdata);
    53  
    54             postStream.Write(formdataBytes, 0, formdataBytes.Length);
    55  
    56             //写入文件内容
    57             //if (item.FileContent != null && item.FileContent.Length > 0)
    58             if (item.IsFile)
    59             {
    60  
    61                 FileStream fs = new FileStream(item.FilePath, FileMode.Open, FileAccess.Read);//可以是其他重载方法
    62                 byte[] byData = new byte[fs.Length];
    63                 fs.Read(byData, 0, byData.Length);
    64                 fs.Close();
    65                 postStream.Write(byData, 0, byData.Length);
    66             }
    67         }
    68         //结尾
    69         var footer = Encoding.UTF8.GetBytes("
    --" + boundary + "--");
    70         postStream.Write(footer, 0, footer.Length);
    71  
    72     }
  • 相关阅读:
    web service 入门实例
    ideal 创建web service项目
    win10上配置hadoop环境
    hadoop-----slaves集中管理与SSH免密登录
    关系的完整性
    关系数据库-----SQL标准语言
    mysql导入excel文件---打开文件失败
    CC2540中的电压检测
    C++ 中静态成员函数访问非静态成员变量的方法
    C 语言中的优先级
  • 原文地址:https://www.cnblogs.com/fightingstepup/p/12050748.html
Copyright © 2011-2022 走看看