I get a multipart/mixed (with a JSON object and a file) like this, as response when I call a web service:
"--Boundary_9_15033478_1405613164044\r\n
Content-Type: application/json
\r\n\r\n{\"docId\":9007492,\"protId\":200,\"protNum\":\"0002084B14\",\"protDate\":\"Wed Jul 16 00:00:00 EEST 2014\",\"categoryId\":1000,\"desc\":\"ѥⷞ ��ƣ䲜��",\"linkNum\":\"ư1\\/00005545\",\"flag1\":\"\",\"flag2\":\"\",\"flag3\":\"\",\"flag4\":\"\",\"stsId\":1,\"stsDesc\":\"WS04: Check Layer I - OK\",\"wsDataList\":[],\"fileName\":\"WsTestToolkitMain.jpg\"}\r\n--Boundary_9_15033478_1405613164044\r\n
Content-Type: application/octet-stream
\r\n\r\n????\0JFIF\0\0`\0`\0\0??\0C\0\a\a\a\a\a\a\b\t\v\t\b\b\n\b\a\a\n\r\n\n\v\f\f\f
...
...
...
??\n?$??\0???????\r\n--Boundary_9_15033478_1405613164044--\r\n"
The way I got it is by getting a Stream of the response (of the HttpWebRequest) and then decode it with UTF-8. This gives me the above String. The question is how can I get the JSON and (more importantly) save the file ?
I tried changing (because they are for multipart/form-data not multipart/mixed) this and this but I can't get the file, maybe because its Content-Type is application/octet-stream . Here is what doesn't work, file appears as it was damaged/corrupted in windows:
// Read the stream into a byte array
byte[] data = ToByteArray(stream);//Source
string content = encoding.GetString(data);
int contentLength = content.Length;//Length
byte[] fileData = new byte[contentLength];//Destination
Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
this.FileContents = fileData;
File.WriteAllBytes("G:\\" + parser.Filename, parser.FileContents);
UPDATE: Followed the answer by Anton Tykhyy (thanks!) but I'm getting an error when
var multipart = await content.ReadAsMultipartAsync () ;
Invalid 'HttpContent' instance provided. It does not have a content-type header value. 'HttpContent' instances must have a content-type header starting with 'multipart/'.
I tried to add this line before
content.Headers.Add("Content-Type", "multipart/mixed");
but now I'm getting another error (that I don't really understand too)
Invalid 'HttpContent' instance provided. It does not have a 'multipart' content-type header with a 'boundary' parameter.
UPDATE 2: Found it, I just had to do this:
var content = new StreamContent(httpResponse.GetResponseStream());
content.Headers.Add("Content-Type", httpResponse.ContentType);
Use ReadAsMultipartAsync in the System.Net.Http.Formatting
assembly, along the lines of
var content = new StreamContent (stream) ;
var multipart = await content.ReadAsMultipartAsync () ;
foreach (var part in multipart)
{
if (part.Headers.ContentType.MediaType == "application/json")
{
// deserialize via stream e.g. part.ReadAsStreamAsync () or via string
// using part.ReadAsStringAsync () to avoid charset grief
}
else
using (var file = File.Create (parser.Filename))
await part.CopyToAsync (file) ;
}
This ought to get you started.
I managed to solve my problem (read the multipart that is), but had to move to .NET 4.5 , if anyone knows the changes in order to work in .NET 4.0 (by replacing "await" and "async" with something else I guess) I would love to know. So that's what I did.
static void Main(string[] args)
{
//some code here...
// POST the request
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
Console.Write(httpResponse.GetResponseStream());
readMultipart(httpResponse).Wait();
}
async static Task readMultipart(HttpWebResponse httpResponse)
{
var content = new StreamContent(httpResponse.GetResponseStream());
content.Headers.Add("Content-Type", httpResponse.ContentType);
var multipart = await content.ReadAsMultipartAsync();
String filename = "";
String json = await multipart.Contents[0].ReadAsStringAsync();
JObject o = JObject.Parse(json);
filename = o["fileName"].ToString();
using (var file = File.Create("C:\\testWS\\" + filename))
await multipart.Contents[1].CopyToAsync(file);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With