Asp.net mvc 写入请求流时请求被中止错误

Asp.net mvc 写入请求流时请求被中止错误,asp.net-mvc,c#-4.0,file-upload,stream,httprequest,Asp.net Mvc,C# 4.0,File Upload,Stream,Httprequest,以上代码适用于小于50mb的视频文件mp4。但当我试图上传一个100mb的文件时,它会抛出异常(请求被中止)。我需要支持最大为1.5gb的文件大小,所以现在我不确定这种方法是否适合如此大的文件大小上传。任何方向正确的建议都会很有帮助…谢谢(我正在尝试将文件上传到Witia服务器) 在这一行抛出异常 --Write(postData,0,postData.Length) 我已尝试更改web.config设置,但无效: httpRuntime targetFramework=“4.5”maxRequ

以上代码适用于小于50mb的视频文件mp4。但当我试图上传一个100mb的文件时,它会抛出异常(请求被中止)。我需要支持最大为1.5gb的文件大小,所以现在我不确定这种方法是否适合如此大的文件大小上传。任何方向正确的建议都会很有帮助…谢谢(我正在尝试将文件上传到Witia服务器) 在这一行抛出异常 --Write(postData,0,postData.Length)

我已尝试更改web.config设置,但无效: httpRuntime targetFramework=“4.5”maxRequestLength=“2048576”executionTimeout=“12000”RequestLength DiskThreshold=“1024”

------异步调用-------

我建议转到异步,直接从文件系统向请求写入文件,以避免内存中1.5GB的三重缓冲(下面的警告未测试)

此外,如果您在web应用程序中执行此操作,并且希望使用异步方法,则需要一直“异步/等待”(所以异步控制器中的异步操作等)


总的来说,我不鼓励在web应用程序中作为请求处理的一部分进行此操作(从用户角度观察到的总时间是上传到应用程序然后再上传到Witia的总和,这可能比客户端超时允许的时间多得多)。在这种情况下,通常最好保存文件并安排其他“后台任务”来执行上载工作。

我不是从磁盘读取文件,而是从HTML文件上载获取文件。我不得不稍微修改上面的解决方案,以适应我的代码。它在没有任何错误的情况下正确运行异步调用。它将成功消息返回给客户端Ux。但是我在WISTIA服务器上没有看到任何文件。。对于1.5 gb的文件来说,它运行得太快了,我不认为它真的会将文件内容发送到WISTIA。。是否有一种方法可以停止所有othr执行,直到我们完成异步调用并获得成功状态…我已经在question@Scorpio您的实现不会引发异常吗?如果我阅读正确,当您开始阅读时,WitiaFilestream将关闭。如果您真的必须将文件保留为字节数组(这很危险,因为在10个并行请求的情况下,您可能最终会分配15 GB),我建议直接从该数组写入请求。我将尝试编辑我的答案,以表明这一点。@Scorpio为不同的方法添加了一个示例和一些一般性建议
public HttpWebResponse PushFileToWistia(byte[] contentFileByteArray, string fileName)
    {
        StringBuilder postDataBuilder = new StringBuilder();
        postDataBuilder.Append("I am appending all the wistia config and setting here");
        byte[] postData = null;
        using (MemoryStream postDataStream = new MemoryStream())
        {
            byte[] postDataBuffer = Encoding.UTF8.GetBytes(postDataBuilder.ToString());
            postDataStream.Write(postDataBuffer, 0, postDataBuffer.Length);
            postDataStream.Write(contentFileByteArray, 0, contentFileByteArray.Length);
            postDataBuffer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--");
            postDataStream.Write(postDataBuffer, 0, postDataBuffer.Length);
            postData = postDataStream.ToArray();
        }

        ServicePointManager.Expect100Continue = false;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfig.WistiaCustomCourseBucket);
        request.Method = "POST";
        request.Expect = String.Empty;
        request.Headers.Clear();
        request.ContentType = "multipart/form-data; boundary=" + boundary;
        request.ContentLength = postData.Length;

        Stream requestStream = request.GetRequestStream();
        requestStream.Write(postData, 0, postData.Length);  //for file > 100mb this call throws and error --the requet was aborted. the request was canceled. 
        requestStream.Flush();
        requestStream.Close();

        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        return response;
        }
       MemoryStream wistiaFileStream = null;
        using (MemoryStream postDataStream = new MemoryStream())
        {
            postDataStream.Write(contentFileByteArray, 0, contentFileByteArray.Length);
            wistiaFileStream = postDataStream;
            postDataStream.Flush();
            postDataStream.Close();
        }

        Stream requestStream = await request.GetRequestStreamAsync();
        await requestStream.WriteAsync(wistiaMetadata, 0, wistiaMetadata.Length);

 using (wistiaFileStream)
        {
            byte[] wistiaFileBuffer = new byte[500*1024];
            int wistiaFileBytesRead = 0;

            while (
                (wistiaFileBytesRead =
                    await wistiaFileStream.ReadAsync(wistiaFileBuffer, 0, wistiaFileBuffer.Length)) != 0)
            {
                await requestStream.WriteAsync(wistiaFileBuffer, 0, wistiaFileBytesRead);
                await requestStream.FlushAsync();
            }
            await requestStream.WriteAsync(requestBoundary, 0, requestBoundary.Length);
        }
public async Task<HttpWebResponse> PushFileToWistiaAsync(string contentFilePath)
{
    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
    string contentBoundary = "\r\n--" + boundary + "\r\n";

    StringBuilder wistiaMetadataBuilder = new StringBuilder();
    wistiaMetadataBuilder.Append("--" + boundary + "\r\n");
    // Append all the wistia config and setting here

    byte[] wistiaMetadata = Encoding.UTF8.GetBytes(wistiaMetadataBuilder.ToString());
    byte[] requestBoundary = Encoding.UTF8.GetBytes(contentBoundary);

    ServicePointManager.Expect100Continue = false;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfig.WistiaCustomCourseBucket);
    request.Method = "POST";
    request.Headers.Clear();
    request.Expect = String.Empty;
    request.ContentType = "multipart/form-data; boundary=" + boundary;

    Stream requestStream = await request.GetRequestStreamAsync();
    await requestStream.WriteAsync(wistiaMetadata, 0, wistiaMetadata.Length);
    using (FileStream wistiaFileStream = new FileStream(contentFilePath, FileMode.Open, FileAccess.Read))
    {
        byte[] wistiaFileBuffer = new byte[500 * 1024];
        int wistiaFileBytesRead = 0;

        while ((wistiaFileBytesRead = await wistiaFileStream.ReadAsync(wistiaFileBuffer, 0, wistiaFileBuffer.Length)) != 0)
        {
            await requestStream.WriteAsync(wistiaFileBuffer, 0, wistiaFileBytesRead);
            await requestStream.FlushAsync();
        }
    }
    await requestStream.WriteAsync(requestBoundary, 0, requestBoundary.Length);

    return (HttpWebResponse)(await request.GetResponseAsync());
}
public HttpWebResponse PushFileToWistia(byte[] contentFileByteArray)
{
    string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
    string contentBoundary = "\r\n--" + boundary + "\r\n";

    StringBuilder wistiaMetadataBuilder = new StringBuilder();
    wistiaMetadataBuilder.Append("--" + boundary + "\r\n");
    // Append all the wistia config and setting here

    byte[] wistiaMetadata = Encoding.UTF8.GetBytes(wistiaMetadataBuilder.ToString());
    byte[] requestBoundary = Encoding.UTF8.GetBytes(contentBoundary);

    ServicePointManager.Expect100Continue = false;

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(AppConfig.WistiaCustomCourseBucket);
    request.Method = "POST";
    request.Headers.Clear();
    request.Expect = String.Empty;
    request.ContentType = "multipart/form-data; boundary=" + boundary;
    request.ContentLength = wistiaMetadata.Length + contentFileByteArray.Length + requestBoundary.Length

    // You can play with SendChunked and AllowWriteStreamBuffering to control the size of chunks you send and performance
    //request.SendChunked = true;
    //request.AllowWriteStreamBuffering = false;

    int contentFileChunkSize = 500 * 1024;
    int contentFileBytesRead = 0;

    Stream requestStream = request.GetRequestStream();
    requestStream.Write(wistiaMetadata, 0, wistiaMetadata.Length);
    while (contentFileBytesRead < contentFileByteArray.Length)
    {
        if ((contentFileBytesRead + contentFileChunkSize) > contentFileByteArray.Length)
        {
            contentFileChunkSize = contentFileByteArray.Length - contentFileBytesRead;
        }

        requestStream.Write(contentFileByteArray, contentFileBytesRead, contentFileChunkSize);
        requestStream.Flush();

        contentFileBytesRead += contentFileChunkSize;
    }
    requestStream.Write(requestBoundary, 0, requestBoundary.Length);
    requestStream.Close();

    // You might need to play with request.Timeout here
    return (HttpWebResponse)request.GetResponse();
}