Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# FileStreamResult不表示下载开始_C#_Asp.net_Asp.net Mvc_Amazon S3 - Fatal编程技术网

C# FileStreamResult不表示下载开始

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,

我在MVC控制器上有以下操作:

  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