Asp.net mvc 写入请求流时请求被中止错误
以上代码适用于小于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应用程序中执行此操作,并且希望使用异步方法,则需要一直“异步/等待”(所以异步控制器中的异步操作等)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
总的来说,我不鼓励在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();
}