c# - 为什么 ASP.NET MVC Controller FileStreamResult 在关闭的流上出错?

标签 c# asp.net asp.net-mvc

我正在尝试从从列表派生的 MVC Controller 返回一个 csv 文件。我根据结合我从文档和 SO 问题中读到的内容为 Controller 提出了以下代码。我一定错过了一些东西,因为我收到了“无法访问关闭的流”的黄色死亡屏幕......

public class ConsumersFileController : Controller
{
    private readonly TDCContext _db = new TDCContext();


    public ActionResult Index()
    {
        IEnumerable<Consumer> list = _db.Consumers.ToList();

        //put List in memory stream object
        MemoryStream memoryStream = new MemoryStream();
        using (memoryStream)
        {
            //return memory stream as file stream result:
            using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream, System.Text.Encoding.UTF8, true))
            {
                foreach (var item in list)
                {
                    var itemBytes = item.Serialize();
                    binaryWriter.Write(itemBytes.Length);
                    binaryWriter.Write(itemBytes);

                }

                FileStreamResult fileStream =
                    new FileStreamResult(memoryStream, "application/txt") {FileDownloadName = "zips.csv"};

                return fileStream;
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _db.Dispose();
        }
        base.Dispose(disposing);
    }

}

这是堆栈跟踪:
[ObjectDisposedException: Cannot access a closed Stream.]
   System.IO.__Error.StreamIsClosed() +59
   System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count) +14731549
   System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response) +93
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +88
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +831
   System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +81
   System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +185
   System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
   System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +52
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
   System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
   System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +43
   System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +607
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +134

如果我在 using 中返回结果,流如何关闭?流块?

最佳答案

你应该删除:

using (memoryStream)
FileStreamResultdispose memoryStream for you .

您的代码不起作用的原因是从 memoryStream 读取的实际工作不在您的代码中 - 它在调用 fileStream.WriteFile 的 MVC 代码中.但是该代码在调用堆栈更高的某个地方执行。到时候WriteFile被调用(需要 memoryStream )你已经处理了它。

关于c# - 为什么 ASP.NET MVC Controller FileStreamResult 在关闭的流上出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45776611/

相关文章:

c# - UWP Combobox SelectedItem 忽略其绑定(bind)值

c# - AutoMapper:将元组映射到元组

c# - 谷歌 reCAPTCHA 的替代方案

asp.net - 在.NET中访问Web服务中的查询字符串(GET请求数组)

c# - 获取 ZipFile 根目录中的文件夹数

c# - 如何在.net core项目中添加View路由?

c# - 让我的 Viewmodel 出现在命名空间下拉列表中

asp.net - 我是否需要输入控件(如复选框、文本框等)的 View 状态?

c# - Azure 应用服务 View 尚未预编译错误

c# - .NET 4.5 并行处理和 for 循环