I am writing a web API service where I want to accept a file (image) and a serialized object (JSON) containing key image information. Having no problems with part of the image, but when I add string content containing a deserialized object, I have problems trying to determine what exactly works accordingly.
The client code looks like this:
HttpClient client = new HttpClient(); MultipartFormDataContent content = new MultipartFormDataContent(); content.Add(new StreamContent(File.Open("c:\\MyImages\\Image00.jpg", FileMode.Open)), "image_file", "Image00.jpg"); ImageKeys ik = new ImageKeys { ImageId = "12345", Timestamp = DateTime.Now.ToString() }; JavaScriptSerializer js = new JavaScriptSerializer(); if (ik != null) { content.Add(new StringContent(js.Serialize(ik), Encoding.UTF8, "application/json"), "image_keys"); } string uri = "http://localhost/MyAPI/api/MyQuery/TransferFile"; var request = new HttpRequestMessage() { RequestUri = new Uri(uri), Method = HttpMethod.Post }; request.Content = content; string responseStr = ""; try { HttpResponseMessage result = client.SendAsync(request).Result; string resultContent = string.Format("{0}:{1}", result.StatusCode, result.ReasonPhrase);
Thus, I include the image file first, and then the serialized object as a StringContent. On the server side, I use the following code to parse the message.
HttpRequestMessage request = this.Request; HttpResponseMessage ret = new HttpResponseMessage(); // // Verify that this is an HTML Form file upload request // if (!request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } string root = "c:\\tmp\\uploads"; if (!Directory.Exists(root)) { Directory.CreateDirectory(root); } // // Create a stream provider for setting up output streams that saves the output under c:\tmp\uploads // If you want full control over how the stream is saved then derive from MultipartFormDataStreamProvider // and override what you need. // MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider(root); try { await request.Content.ReadAsMultipartAsync(streamProvider); foreach (var file in streamProvider.Contents) { if (file.Headers.ContentDisposition.Name == "image_file") { FileInfo finfo = new FileInfo(streamProvider.FileData.First().LocalFileName); string destFile = Path.Combine(root, streamProvider.FileData.First().Headers.ContentDisposition.FileName.Replace("\"", "")); // // File.Move cannot deal with duplicate files // Ensure that the target does not exist. // if (File.Exists(destFile)) { File.Delete(destFile); } File.Move(finfo.FullName, destFile); } else if (file.Headers.ContentDisposition.Name == "image_keys") { // deserialize key class string str = file.ReadAsStringAsync().Result; JavaScriptSerializer js = new JavaScriptSerializer(); ImageKeys ik = js.Deserialize<ImageKeys>(str); } } ret.StatusCode = HttpStatusCode.OK; ret.Content = new StringContent("File uploaded."); } catch (Exception ex) { ret.StatusCode = HttpStatusCode.UnsupportedMediaType; ret.Content = new StringContent("File upload failed."); } return ret;
The foreach loop tries to process each element in multi-part content as a file, but I want to consider different types of content separately, but it is not clear to me how they are defined. Thanks
source share