How do I dispose my filestream when implementing a file download in ASP.NET?

后端 未结 2 1184
醉酒成梦
醉酒成梦 2020-11-27 06:40

I have a class DocumentGenerator which wraps a MemoryStream. So I have implemented IDisposable on the class.

I can\'t see how/

相关标签:
2条回答
  • 2020-11-27 06:57

    Just to add to what Darin has said, it's important to note this concept:

    public Stream GetDownloadFile(...)
    {
      using (var stream = new MemoryStream()) {
        return stream;
      }
    }
    
    public Stream GetDownloadFile(...)
    {
      using (var generator = DocumentGenerator.OpenTemplate(path))
      {
        // Document manipulation.
    
        return File(generator.GetDocumentStream(), "text/plain", filename);
      }
    }
    

    Regardless of how you are using it in your method, the using block ensures that Dispose is always called, this is important when you consider to use the result of the using block as a return statement, it won't stop it from being disposed....

    0 讨论(0)
  • 2020-11-27 06:59

    You don't need to dispose the stream. It will be disposed by the FileStreamResult.WriteFile method. Code excerpt from this class:

    public FileStreamResult(Stream fileStream, string contentType) : base(contentType)
    {
        if (fileStream == null)
        {
            throw new ArgumentNullException("fileStream");
        }
        this.FileStream = fileStream;
    }
    
    protected override void WriteFile(HttpResponseBase response)
    {
        Stream outputStream = response.OutputStream;
        using (this.FileStream)
        {
            byte[] buffer = new byte[0x1000];
            while (true)
            {
                int count = this.FileStream.Read(buffer, 0, 0x1000);
                if (count == 0)
                {
                    return;
                }
                outputStream.Write(buffer, 0, count);
            }
        }
    }
    

    Notice the using. When you call File(dg.GetDocumentStream(), "text/plain", filename) from your controller this invokes the constructor which stores the stream into a public property which is disposed during the rendering.

    Conclusion: you don't need to worry about disposing the stream obtain with dg.GetDocumentStream().

    0 讨论(0)
提交回复
热议问题