上传和接收使用ASP.NET进行http压缩的大型文件,可以实现mime multipart流的意外结束"

时间:2015-04-02 18:54:46

标签: c# asp.net file-upload asp.net-web-api2 large-files

我很难在ASP.NET中尝试发送带有HTTP文件上传的大文件。

目标是传输大于2GB的内容,压缩以节省带宽。发送3GB未压缩效果很好,所有文件都可以在磁盘上正确接收和保存。然而,当我使用压缩(gzip或deflate)时,我从接收API收到以下错误:

Unexpected end of MIME multipart stream. MIME multipart message is not complete.

事情是,只有在发送大量请求(大约300MB是上限)时,才会出现异常。上传200MB压缩效果很好。

这是上传代码:

using (var client = new HttpClient())
{
    using (var content = new MultipartFormDataContent())
    {
        client.BaseAddress = new Uri(fileServerUrl);
        client.DefaultRequestHeaders.TransferEncodingChunked = true;

        CompressedContent compressedContent = new CompressedContent(content, "gzip");

        var request = new HttpRequestMessage(HttpMethod.Post, "/api/fileupload/")
        {
            Content = compressedContent
        };

        var uploadResponse = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
    }
}

CompressedContent类是来自WebApiContrib帮助程序集的类

这是接收端

// CustomStreamProvider is an implementation to store the files uploaded on the disk
var streamProvider = new CustomStreamProvider(uploadPath);
var res = await Request.Content.ReadAsMultipartAsync(streamProvider);
streamProvider.FileData.Select(file => new FileInfo(file.LocalFileName)).Select(fi => fi.FullName)

你能告诉我一个问题是什么吗?为什么较大的内容(大于300MB)看起来压缩不当而较小的内容传输得很好?

3 个答案:

答案 0 :(得分:2)

尝试在输入中添加名称,如下所示:

<input type="file" id="fileInput" name="fileInput"/>

或使用自定义流附加ASP.NET web api期望的换行符:

Stream reqStream = Request.Content.ReadAsStreamAsync().Result;
MemoryStream tempStream = new MemoryStream();
reqStream.CopyTo(tempStream);

tempStream.Seek(0, SeekOrigin.End);
StreamWriter writer = new StreamWriter(tempStream);
writer.WriteLine();
writer.Flush();
tempStream.Position = 0;

StreamContent streamContent = new StreamContent(tempStream);
foreach(var header in Request.Content.Headers)
{
    streamContent.Headers.Add(header.Key, header.Value);
}

// Read the form data and return an async task.
await streamContent.ReadAsMultipartAsync(provider);

希望这会有所帮助......

答案 1 :(得分:1)

您是否正在以块的形式压缩文件?如果您能够发送未压缩的文件,那么很明显,问题是您的压缩例程。使用gzip或Deflate开箱即用的文件大小有限制。因此,您需要压缩块。

提示 调试压缩例程。尝试压缩文件并将其保存到硬盘驱动器中,看看它是否可读。

看看这个article

答案 2 :(得分:1)

检查content-length是什么,HTTP服务器端例程不希望您发送不同的内容长度。您可能正在发送原始文件大小的内容长度,而您正在发送压缩内容,而MultiPart解析器期望数据等于内容长度。

相反,您发送一个压缩文件并在服务器端提取它,并且在应用程序级别使压缩和解压缩不同,而不是插入http协议。

您必须确保压缩/解压缩的顺序和内容长度都是正确的。据我所知,上传压缩在HTTP协议上并不常见。