Multipart form POST in C#

关于Multipart message的格式,可以参考W3C的网站,本文集中演示怎样用C#代码实现该类消息的传送。

[code:c#]

public static class FormUpload
    {
        public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
        {
            string formDataBoundary = “—————————–28947758029299”;
            string contentType = “multipart/form-data; boundary=” + formDataBoundary;

            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);

            return PostForm(postUrl, userAgent, contentType, formData);
        }
        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
        {
            HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;

            if (request == null)
            {
                throw new NullReferenceException(“request is not a http request”);
            }

            // Set up the request properties

            request.Method = “POST”;
            request.ContentType = contentType;
            request.UserAgent = userAgent;
            request.CookieContainer = new CookieContainer();
            request.ContentLength = formData.Length;  // We need to count how many bytes we’re sending.

            using (Stream requestStream = request.GetRequestStream())
            {
                // Push it out there

                requestStream.Write(formData, 0, formData.Length);
                requestStream.Close();
            }

            return request.GetResponse() as HttpWebResponse;
        }

        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
        {
            Stream formDataStream = new System.IO.MemoryStream();
            Encoding encoding = Encoding.Default;

            foreach (var param in postParameters)
            {
                if (param.Value is byte[])
                {
                    byte[] fileData = param.Value as byte[];

                    // Add just the first part of this param, since we will write the file data directly to the Stream

                    string header = string.Format(“–{0}\r\nContent-Disposition: form-data; name=\”{1}\”; filename=\”{2}\”;\r\nContent-Type: application/octet-stream\r\n\r\n”, boundary, param.Key, param.Key);
                    formDataStream.Write(encoding.GetBytes(header), 0, header.Length);

                    // Write the file data directly to the Stream, rather than serializing it to a string.

                    formDataStream.Write(fileData, 0, fileData.Length);
                }
                else
                {
                    string postData = string.Format(“–{0}\r\nContent-Disposition: form-data; name=\”{1}\”\r\n\r\n{2}\r\n”, boundary, param.Key, param.Value);
                    formDataStream.Write(encoding.GetBytes(postData), 0, postData.Length);
                }
            }

            // Add the end of the request

            string footer = “\r\n–” + boundary + “–\r\n”;
            formDataStream.Write(encoding.GetBytes(footer), 0, footer.Length);

            // Dump the Stream into a byte[]

            formDataStream.Position = 0;
            byte[] formData = new byte[formDataStream.Length];
            formDataStream.Read(formData, 0, formData.Length);
            formDataStream.Close();

            return formData;
        }

    }

[/code]

上面的FormUpload类目的是构造消息,下面就是FormUpload类的调用方法:

[code:c#]

        static void Main(string[] args)
        {
            // Read file data

            FileStream fs = new FileStream(“c:\\example.txt”, FileMode.Open, FileAccess.Read);
            byte[] data = new byte[fs.Length];
            fs.Read(data, 0, data.Length);
            fs.Close();

            // Generate post objects

            Dictionary<string, object> postParameters = new Dictionary<string, object>();
            postParameters.Add(“user”, “fdreader”);
            postParameters.Add(“pass”, “pl!mnsj@38“);
            postParameters.Add(“logfile”, “example.txt”);
            postParameters.Add(“example.txt”, data);

            // Create request and receive response

            string postURL = @”http://bigbird.itsc.cuhk.edu.hk/etickettest/palm/attendance.asp“;
            string userAgent = “Someone”;
            HttpWebResponse webResponse = FormUpload.MultipartFormDataPost(postURL, userAgent, postParameters);

            // Process response

            StreamReader responseReader = new StreamReader(webResponse.GetResponseStream());
            string fullResponse = responseReader.ReadToEnd();
            webResponse.Close();
            Console.Write(fullResponse);
            Console.ReadKey();
        }

[/code]