在C#中读取multipart / mixed(.NET 4.0)

时间:2014-07-18 08:34:00

标签: c# multipart

我得到一个这样的multipart / mixed(带有JSON对象和文件)作为响应,当我调用Web服务时:

"--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"

我得到它的方法是获取响应流(HttpWebRequest),然后用UTF-8解码它。这给了我上面的字符串。 问题是如何获取JSON和(更重要的是)保存文件

我尝试更改(因为它们适用于多部分/表单数据而不是多部分/混合)thisthis但我无法获取该文件,可能是因为其Content-Type application / octet-stream 。这是什么不起作用,文件出现,因为它在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);

更新 跟随Anton Tykhyy的回答(谢谢!)但是我在

时遇到错误
var multipart = await content.ReadAsMultipartAsync () ;

提供的“HttpContent”实例无效。它没有内容类型标头值。 'HttpContent'实例必须有一个以'multipart /'开头的内容类型标题。

我尝试在

之前添加此行
content.Headers.Add("Content-Type", "multipart/mixed");

但现在我又收到了另一个错误(我也不太明白)

提供的“HttpContent”实例无效。它没有带有'boundary'参数的'multipart'内容类型标题。

更新2: 找到它,我只需要这样做:

    var content = new StreamContent(httpResponse.GetResponseStream());
    content.Headers.Add("Content-Type", httpResponse.ContentType);

2 个答案:

答案 0 :(得分:4)

使用ReadAsMultipartAsync中的System.Net.Http.Formatting assembly,与

一致
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) ;
}

这应该让你开始。

答案 1 :(得分:1)

我设法解决了我的问题(阅读多部分),但必须转移到.NET 4.5 ,如果有人知道更改以便在 .NET 4.0中工作< / strong>(通过用其他东西代替“await”和“async”我猜)我很想知道。这就是我所做的。

  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);
    }