title: Upload files with POST from a C#-WinForm using WebBrowser-Instance?
body: <p>I want to make a POST to a PHP site from a C# WinForm Application in a Browser window (or a WebBrowser-instance) with .net 2.0 and I need to get the data and the headers-argments right. Like:</p>
  
  <pre><code>webBrowser1.Navigate("http://mypublishservice.com/publish_picture.php","_SELF",X,Y); 
  </code></pre>
  
  <p>The question is: What should be X and Y? I know a have to fill all headers and file data in a byte[] array and add some additional headers as strings. I made examples of the webform below and examined them with firebug. So i know how the POST data should look like. I even created a HttpWebRequest which was ok, but I need a <strong>WebBrowser</strong> (reasons below) to start the Post-Request. So i am lost. I have tried many options, e.g.  <a href="https://stackoverflow.com/questions/566462/upload-files-with-httpwebrequest-multipart-form-data">Upload files with HTTPWebrequest (multipart/form-data)</a>. Maybe there is a better way, by creating a HttpWebrequest and than passing this to a WebBrowser-instance or something like that?</p>
  
  <p>Here is a web form to call the publish_picture.php page that works fine:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
    &lt;head&gt;
      &lt;title&gt;&lt;/title&gt;
      &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;div&gt;
        &lt;form enctype="multipart/form-data" action="http://mypublishservice.com/publish_picture.php" method="POST"&gt;
  
        Please choose a photo:
        &lt;input name="source" type="file"&gt;&lt;br/&gt;&lt;br/&gt;
        Say something about this photo:
        &lt;input name="message" type="text" value=""&gt;&lt;br/&gt;&lt;br/&gt;
        &lt;input type="submit" value="Upload"/&gt;&lt;br/&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>In case you ask why I want to do it THIS way, here some thoughts to defend my silly decision ;)</p>
  
  <p>Why a WebBrowser-instance and not a simple HttpWebrequest? Because the target service (e.g. Facebook) needs (or seems to need) a proper Browser! 
  Why not the target service APIs (e.g. Facebook API)? Found out, that Desktop-Web-communication is not good (too many 400-Errors).</p>
  
  <p>UPDATE 2:</p>
  
  <p>Looks better.  Still I get an error but it might be the PHP page itself. Is this what you have in mind?</p>
  
  <pre><code>   public static byte[] PrepareUploadFiles(string address, IEnumerable&lt;UploadFile&gt; 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 &lt;= 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); 
          }
  
  
      }
  </code></pre>