Quantcast
Channel: Chui's Counterpoint » WPF
Viewing all articles
Browse latest Browse all 8

Asynchronous Multipart POST with C#

$
0
0

Here’s a re-usable code-snippet for POSTing multipart/mime requests.

Sample Usage:

Status = "Logging In";

PostRequest(
  this.LoginUri,
  null, /* not posting any files */
  new { username = UserName, password = Password },
    (WebResponse response) =>
    {
        string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
        Status = "Logged In";
    });

PostRequest(
  this.LoginUri,
  new [] { new UploadFile { ContentType="text/plain", Name="files", Filename="myfile.txt", Stream=File.OpenRead("myfile.txt")}}, 
  new { username = UserName, password = Password },
    (WebResponse response) =>
    {
        string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
        Status = "File Uploaded";
    });

private CookieContainer _cookieContainer = new CookieContainer();

private void PostRequest(Uri address, IEnumerable<UploadFile> files, object values, Action<WebResponse> handleResponse)
{
    PostRequest(address, files, ToNameValueCollection(values), handleResponse);
}

private void PostRequest(Uri address, IEnumerable<UploadFile> files, NameValueCollection values, Action<WebResponse> handleResponse)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(address);
    request.CookieContainer = _cookieContainer;
    request.Method = "POST";
    var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    boundary = "--" + boundary;

    request.BeginGetRequestStream(new AsyncCallback(r =>
    {
        using (var requestStream = request.EndGetRequestStream(r))
        {
            // Write the values
            if (values != null)
            {
                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
            if (files != null)
            {
                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);
                    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);
            requestStream.Close();

            request.BeginGetResponse(new AsyncCallback(r2 =>
            {
                try
                {
                    var response = request.EndGetResponse(r2);
                    handleResponse(response);
                }
                catch (WebException exc)
                {
                    Status = exc.Message;
                }
            }), null);
        }
    }), null);

} // PostRequest

private static NameValueCollection ToNameValueCollection(object o)
{
    var nvc = new NameValueCollection();
    o.GetType().GetProperties()
    .ToList()
    .ForEach(pi => nvc.Add(pi.Name, pi.GetValue(o, null).ToString()));
    return nvc;
}

    // Helper class
    public class UploadFile
    {
        public UploadFile()
        {
            ContentType = "application/octet-stream";
        }
        public string Name { get; set; }
        public string Filename { get; set; }
        public string ContentType { get; set; }
        public Stream Stream { get; set; }
    }

The post Asynchronous Multipart POST with C# appeared first on Chui's Counterpoint.


Viewing all articles
Browse latest Browse all 8

Latest Images

Trending Articles



Latest Images