3

要从操作中返回文件,请执行以下操作:

return File(myStream, ...);

这意味着您不能包含myStream在 using 语句中,这让我很难过。假设我在 using 语句中有多个内容,以便获取我想要返回的文件的内容。例如,我从存储为 SQL 文件流的数据库中返回一个文件:

using (SqlConnection connection = ...)
{
    using (SqlTransaction trans = ...)
    {
        using (SqlFileStream fileStream = ...)
        {
            return File(fileStream, ...);
        }
    }
}

我想在 using 语句中执行此操作,以确保在文件流式传输后流、事务和连接都关闭。当然,我不能这样做,因为一旦执行 return 语句,我正在使用的所有东西都将关闭。我确实意识到我发送的流File(...)将被关闭,但其他东西将保持打开状态(理论上)。

我的解决方案是这样的:

SqlConnection connection = ...;
SqlTransaction trans = ...;
SqlFileStream fileStream = ...;

return new DisposableFileStreamResult(fileStream, MimeMapping.GetMimeMapping(file.Name), file.Name, () =>
{
    fileStream.Dispose();  //It's already disposed but for clarity...
    trans.Dispose();
    connection.Dispose();
});

DisposableFileStreamResult 看起来像:

public class DisposableFileStreamResult : FileStreamResult
{
    public Action Cleanup { get; set; }

    public DisposableFileStreamResult(Stream stream, string contentType) : this(stream, contentType, null) { }

    public DisposableFileStreamResult(Stream stream, string contentType, string fileDownloadName) : this(stream, contentType, fileDownloadName, null) { }

    public DisposableFileStreamResult(Stream stream, string contentType, string fileDownloadName, Action cleanup)
        : base(stream, contentType)
    {
        base.FileDownloadName = fileDownloadName;
        this.Cleanup = cleanup;
    }

    protected override void WriteFile(HttpResponseBase response)
    {
        base.WriteFile(response);

        if (this.Cleanup != null)
            this.Cleanup();
    }
}

我不想将一堆东西读入内存;我不喜欢字节数组!有没有使用 MVC4 的内置方法来做到这一点?如果我必须返回一个大文件怎么办?我的临时解决方案是合理的,还是矫枉过正或没有必要?

4

0 回答 0