C# FileStreamResult不表示下载开始
我在MVC控制器上有以下操作:C# FileStreamResult不表示下载开始,c#,asp.net,asp.net-mvc,amazon-s3,C#,Asp.net,Asp.net Mvc,Amazon S3,我在MVC控制器上有以下操作: public async Task<FileStreamResult> Contact() { IAmazonS3 s3Client = GetS3Client(); GetObjectRequest request = new GetObjectRequest { BucketName = bucketName,
public async Task<FileStreamResult> Contact()
{
IAmazonS3 s3Client = GetS3Client();
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = objectKey,
};
GetObjectResponse response = await s3Client.GetObjectAsync(request).ConfigureAwait(false);
return File(response.ResponseStream, "application/octet-stream", "SomeFile.exe");
}
公共异步任务联系人()
{
IAmazonS3 s3Client=GetS3Client();
GetObjectRequest=新的GetObjectRequest
{
BucketName=BucketName,
Key=objectKey,
};
GetObjectResponse response=await s3Client.GetObjectAsync(请求).ConfigureAwait(错误);
返回文件(response.ResponseStream、“应用程序/八位字节流”、“SomeFile.exe”);
}
我正在测试的文件约为10-30MB
当此操作由页面上的按钮触发时,不会指示下载开始。浏览器会静默地等待文件完全可用(这需要相当长的时间),然后突然将其显示为已下载
为什么不显示下载已开始并正在进行?如何实现这一点
文件非常大,我希望将它们发送/流式传输到客户端,而无需加载到内存或预先保存在服务器上,因此我想这就是FileStreamResult的作用?好吧,简单的答案似乎是:
下载开始和进度在浏览器中不可见,因为未设置内容长度,因此浏览器无法从
文件流结果中找出它们
所以,设置它就足够了。对我来说,通过扩展ActionResult
,可以设置长度,这是最有效的方法:
public class FileStreamWithLengthResult : ActionResult
{
private Stream stream;
private string mimeType;
private string fileName;
private long contentLength;
public FileStreamWithLengthResult(Stream stream,string mimeType,string fileName)
{
this.stream = stream;
this.mimeType = mimeType;
this.fileName = fileName;
this.contentLength = stream.Length;
}
public override void ExecuteResult(ControllerContext context)
{
var response = context.HttpContext.Response;
response.BufferOutput = false;
response.Headers.Add("Content-Type", mimeType);
response.Headers.Add("Content-Length", contentLength.ToString());
response.Headers.Add("Content-Disposition", "attachment; filename=" + fileName);
stream.CopyTo(response.OutputStream);
}
}
然后动作代码就简单到
public async Task<FileStreamWithLengthResult> Download()
{
IAmazonS3 s3Client = GetS3Client();
GetObjectRequest request = new GetObjectRequest
{
BucketName = bucketName,
Key = objectKey,
};
GetObjectResponse response = await s3Client.GetObjectAsync(request).ConfigureAwait(false);
return new FileStreamWithLengthResult(response.ResponseStream, "application/octet-stream", "SomeFile.exe");
}
我想这些都指向同一个对象实例,但不确定为什么它不起作用。无论如何,自定义FileStreamWithLengthResult工作正常,看起来更优雅:)
this.ControllerContext.HttpContext.Response.AddHeader("Content-Length", response.ResponseStream.Length.ToString()); //not worked
this.Response.AddHeader("Content-Length", response.ResponseStream.Length.ToString()); //not worked
this.HttpContext.Response.AddHeader("Content-Length", response.ResponseStream.Length.ToString()); //not worked