DataContractQueryStringSerializer
) while the other for multipart upload form post (DataContractMultiPartSerializer
).If you only want to have the working code, just copy the code below. Detail explanation is available at Multi-Part Form Post in Shane's Shelf
- public static class Extensions
- {
- public static void PostFormAsync(this HttpWebRequest request, object parameters, AsyncCallback callback)
- {
- request.Method = "POST";
- request.ContentType = "application/x-www-form-urlencoded";
- request.BeginGetRequestStream(new AsyncCallback(asyncResult =>
- {
- Stream stream = request.EndGetRequestStream(asyncResult);
- DataContractQueryStringSerializer ser = new DataContractQueryStringSerializer();
- ser.WriteObject(stream, parameters);
- stream.Close();
- request.BeginGetResponse(callback, request);
- }), request);
- }
- public static void PostMultiPartAsync(this HttpWebRequest request, object parameters, AsyncCallback callback)
- {
- request.Method = "POST";
- string boundary = "---------------" + DateTime.Now.Ticks.ToString();
- request.ContentType = "multipart/form-data; boundary=" + boundary;
- request.BeginGetRequestStream(new AsyncCallback(asyncResult =>
- {
- Stream stream = request.EndGetRequestStream(asyncResult);
- DataContractMultiPartSerializer ser = new DataContractMultiPartSerializer(boundary);
- ser.WriteObject(stream, parameters);
- stream.Close();
- request.BeginGetResponse(callback, request);
- }), request);
- }
- }
- public class DataContractQueryStringSerializer
- {
- public void WriteObject(Stream stream, object data)
- {
- StreamWriter writer = new StreamWriter(stream);
- if (data != null)
- {
- if (data is Dictionary<string, string>)
- {
- foreach (var entry in data as Dictionary<string, string>)
- {
- writer.Write("{0}={1}&", entry.Key, entry.Value);
- }
- }
- else
- {
- foreach (var prop in data.GetType().GetFields())
- {
- foreach (var attribute in prop.GetCustomAttributes(true))
- {
- if (attribute is DataMemberAttribute)
- {
- DataMemberAttribute member = attribute as DataMemberAttribute;
- writer.Write("{0}={1}&", member.Name ?? prop.Name, prop.GetValue(data));
- }
- }
- }
- foreach (var prop in data.GetType().GetProperties())
- {
- if (prop.CanRead)
- {
- foreach (var attribute in prop.GetCustomAttributes(true))
- {
- if (attribute is DataMemberAttribute)
- {
- DataMemberAttribute member = attribute as DataMemberAttribute;
- writer.Write("{0}={1}&", member.Name ?? prop.Name, prop.GetValue(data, null));
- }
- }
- }
- }
- }
- writer.Flush();
- }
- }
- }
- public class DataContractMultiPartSerializer
- {
- private string boundary;
- public DataContractMultiPartSerializer(string boundary)
- {
- this.boundary = boundary;
- }
- private void WriteEntry(StreamWriter writer, string key, object value)
- {
- if (value != null)
- {
- writer.Write("--");
- writer.WriteLine(boundary);
- if (value is FileInfo)
- {
- FileInfo f = value as FileInfo;
- writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""; filename=""{1}""", key, f.Name);
- writer.WriteLine("Content-Type: application/octet-stream");
- writer.WriteLine("Content-Length: " + f.Length);
- writer.WriteLine();
- writer.Flush();
- Stream output = writer.BaseStream;
- Stream input = f.OpenRead();
- byte[] buffer = new byte[4096];
- for (int size = input.Read(buffer, 0, buffer.Length); size > 0; size = input.Read(buffer, 0, buffer.Length))
- {
- output.Write(buffer, 0, size);
- }
- output.Flush();
- writer.WriteLine();
- }
- else
- {
- writer.WriteLine(@"Content-Disposition: form-data; name=""{0}""", key);
- writer.WriteLine();
- writer.WriteLine(value.ToString());
- }
- }
- }
- public void WriteObject(Stream stream, object data)
- {
- StreamWriter writer = new StreamWriter(stream);
- if (data != null)
- {
- if (data is Dictionary<string, object>)
- {
- foreach (var entry in data as Dictionary<string, object>)
- {
- WriteEntry(writer, entry.Key, entry.Value);
- }
- }
- else
- {
- foreach (var prop in data.GetType().GetFields())
- {
- foreach (var attribute in prop.GetCustomAttributes(true))
- {
- if (attribute is DataMemberAttribute)
- {
- DataMemberAttribute member = attribute as DataMemberAttribute;
- WriteEntry(writer, member.Name ?? prop.Name, prop.GetValue(data));
- }
- }
- }
- foreach (var prop in data.GetType().GetProperties())
- {
- if (prop.CanRead)
- {
- foreach (var attribute in prop.GetCustomAttributes(true))
- {
- if (attribute is DataMemberAttribute)
- {
- DataMemberAttribute member = attribute as DataMemberAttribute;
- WriteEntry(writer, member.Name ?? prop.Name, prop.GetValue(data, null));
- }
- }
- }
- }
- }
- }
- writer.Write("--");
- writer.Write(boundary);
- writer.WriteLine("--");
- writer.Flush();
- }
- }
First a PHP file
- <?php
- print_r($_REQUEST);
- $src = $_FILES['y']['tmp_name'];
- $dest = "C:\\Windows\\Temp\\".$_FILES['y']['name'];
- echo $src;
- echo "\r\n";
- echo $dest;
- echo @copy($src, $dest);
- ?>
- public partial class Page : UserControl
- {
- public Page()
- {
- InitializeComponent();
- // Create a request object
- HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("http://localhost/rms/test.php"));
- OpenFileDialog dlg = new OpenFileDialog();
- if (dlg.ShowDialog().Value)
- {
- request.PostMultiPartAsync(new Dictionary<string, object> { { "x", "1" }, { "y", dlg.File } }, new AsyncCallback(asyncResult =>
- {
- HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult);
- Stream responseStream = response.GetResponseStream();
- StreamReader reader = new StreamReader(responseStream);
- this.Dispatcher.BeginInvoke(delegate
- {
- // output is a TextBlock
- output.Text = reader.ReadToEnd();
- response.Close();
- });
- }));
- }
- }
- }
- new Dictionary<string, object> { { "x", "1" }, { "y", dlg.File } }
with
- new Point(){X=1, Y=2}
given the point class is like this:
- [DataContract]
- public class Point
- {
- [DataMember]
- public int X { get; set; }
- [DataMember(Name="y")]
- public int Y { get; set; }
- }
4 comments:
Cool! The multipart handling was exactly what I needed. Nice work!
Hi,
I failed in EndGetResponse(), and got security exception.
What will the encoding data would like?
Could you give me an example?
Thanks a lot~
Could you post the receiving part? Meaning, how to take the multipart request in the server (Jersey) and process the multipart request?
It's just a multi-part form post. PHP and standard Java Web Container (e.g. Tomcat) will be able to process it natively.
Post a Comment