使用WebBrowser实例从C#-WinForm通过POST上传文件?

| 我想使用.net 2.0从浏览器窗口(或WebBrowser-instance)中的C#WinForm应用程序中进行POST到PHP站点,我需要正确获取数据和headers-argments。喜欢:
webBrowser1.Navigate(\"http://mypublishservice.com/publish_picture.php\",\"_SELF\",X,Y); 
问题是:X和Y应该是什么?我知道必须将所有标头和文件数据填充到byte []数组中,并添加一些其他标头作为字符串。我在下面制作了Webform的示例,并使用Firebug对其进行了检查。所以我知道POST数据应该是什么样子。我什至创建了一个可以的HttpWebRequest,但是我需要一个WebBrowser(下面的原因)来启动Post-Request。所以我迷路了。我尝试了很多选择,例如使用HTTPWebrequest(多部分/表单数据)上传文件。通过创建HttpWebrequest并将其传递给WebBrowser-instance或类似的方法,也许是一种更好的方法? 这是一个可以正常运行publish_picture.php页面的Web表单:
<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">
  </head>
  <body>
    <div>
      <form enctype=\"multipart/form-data\" action=\"http://mypublishservice.com/publish_picture.php\" method=\"POST\">

      Please choose a photo:
      <input name=\"source\" type=\"file\"><br/><br/>
      Say something about this photo:
      <input name=\"message\" type=\"text\" value=\"\"><br/><br/>
      <input type=\"submit\" value=\"Upload\"/><br/>
      </form>
    </div>
  </body>
</html>
如果您问我为什么要这样做,这里有一些想法可以捍卫我的愚蠢决定;) 为什么是WebBrowser实例而不是简单的HttpWebrequest?因为目标服务(例如Facebook)需要(或似乎需要)适当的浏览器! 为什么不使用目标服务API(例如Facebook API)?结果发现,桌面Web通讯不好(太多的400错误)。 更新2: 看起来更好。仍然出现错误,但可能是PHP页面本身。这是您要记住的吗?
   public static byte[] PrepareUploadFiles(string address, IEnumerable<UploadFile> files, NameValueCollection values, out string header)
   {

       using (var requestStream = new MemoryStream())
       {
           var boundary = \"---------------------------\" + DateTime.Now.Ticks.ToString(\"x\"); //, NumberFormatInfo.InvariantInfo);
           header = \"multipart/form-data; boundary=\" + boundary;
           var boundaryBuffer2 = Encoding.ASCII.GetBytes(header);
               requestStream.Write(boundaryBuffer2, 0, boundaryBuffer2.Length);
               boundary = \"--\" + boundary;
               // Write the values
               foreach (string name in values.Keys)
           {
               var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
               requestStream.Write(buffer, 0, buffer.Length);
               buffer = Encoding.ASCII.GetBytes(string.Format(\"Content-Disposition: form-data; name=\\\"{0}\\\"{1}{1}\", name, Environment.NewLine));
               requestStream.Write(buffer, 0, buffer.Length);
               buffer = Encoding.UTF8.GetBytes(values[name] + Environment.NewLine);
               requestStream.Write(buffer, 0, buffer.Length);
           }

           // Write the files
           foreach (var file in files)
           {
               var buffer = Encoding.ASCII.GetBytes(boundary + Environment.NewLine);
               requestStream.Write(buffer, 0, buffer.Length);
               buffer = Encoding.UTF8.GetBytes(string.Format(\"Content-Disposition: form-data; name=\\\"{0}\\\"; filename=\\\"{1}\\\"{2}\", file.Name, file.Filename, Environment.NewLine));
               requestStream.Write(buffer, 0, buffer.Length);
               buffer = Encoding.ASCII.GetBytes(string.Format(\"Content-Type: {0}{1}{1}\", file.ContentType, Environment.NewLine));
               requestStream.Write(buffer, 0, buffer.Length);

               CopyStream(file.Stream, requestStream); // file.Stream.CopyTo(requestStream);

               buffer = Encoding.ASCII.GetBytes(Environment.NewLine);
               requestStream.Write(buffer, 0, buffer.Length);
           }

           var boundaryBuffer = Encoding.ASCII.GetBytes(boundary + \"--\");
           requestStream.Write(boundaryBuffer, 0, boundaryBuffer.Length);

           return requestStream.ToArray(); 

       }

   }

   public static void CopyStream(Stream input, Stream output)
   {
       byte[] buffer = new byte[32768];
       while (true)
       {
           int read = input.Read(buffer, 0, buffer.Length);
           if (read <= 0)
               return;
           output.Write(buffer, 0, read);
       }
 }



public void Upload()
{
  using (var stream1 = File.Open(Support.EXAMPLEIMAGE, FileMode.Open))
        {
            var files = new[] 
                 {
                new UploadFile
               {
            Name = \"source\",  // 1
            Filename = Support.EXAMPLEIMAGE,
            ContentType = \"image/jpeg\",   // 2
            Stream = stream1
              }

          };

          var values = new NameValueCollection
        {
         { \"message\", \"a text\" }   // 3

         };


             string contentType;  // 4. do I need it  
            byte[] dataToPost = Support.PrepareUploadFiles(Support.URL, files, values, out contentType); // 5. out contentType = what should be the result vaule?
            //PrepareUploadFiles(url, files, values, out contentType);
            webBrowser1.Navigate(Support.URL, null, dataToPost, \"Content-Type: \" + contentType + Environment.NewLine); 
        }


    }
    
已邀请:
        我个人喜欢使用ParseQueryString方法,因为它可以正确编码参数:
var values = HttpUtility.ParseQueryString(string.Empty);
values[\"param1\"] = \"param1 value\";
values[\"param2\"] = \"param2 value\";
values[\"param3\"] = \"param3 value\";
var dataToPost = Encoding.UTF8.GetBytes(values.ToString());
var url = \"http://mypublishservice.com/publish_picture.php\";
var contentType = \"Content-Type: application/x-www-form-urlencoded\" + Environment.NewLine;
webBrowser1.Navigate(url, null, dataToPost, contentType); 
现在,由于您正在尝试上传文件,因此这将变得有些困难。我写了一篇博客文章,阐述了如何生成允许上传多个文件的“ 4”请求。因此,您可以调整此处显示的UploadFiles方法,使其仅返回POST正文,而不进行实际的上传,然后执行以下操作:
string contentType;
byte[] dataToPost = PrepareUploadFiles(url, files, values, out contentType);
webBrowser1.Navigate(url, null, dataToPost, \"Content-Type: \" + contentType + Environment.NewLine); 
    

要回复问题请先登录注册