2

i am using below code to download the word document when i click on button in view but some how it seems like not working and getting below error:

ObjectDisposedException: Cannot access a closed Stream. System.IO.MemoryStream.Read(byte[] buffer, int offset, int count)

and below is the code that i am using

 public IActionResult CreateDocument()
 {
        using (MemoryStream mem = new MemoryStream())
        {
            using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document))
            {
                var mainDocumentPart = wordDoc.AddMainDocumentPart();
                Body body = new Body();
                mainDocumentPart.Document = new Document(body);
                Document doc = new Document();

                /// Add header
                ApplyHeader(wordDoc);
                List<string> bulletedList = new List<string>() { "This is bulleted point 1", "This is bulleted point 2", "This is bulleted point 3" };
                var runList = ListOfStringToRunList(bulletedList);

                // Add buletted points
                ApplyBulletedList(wordDoc, body, doc, runList);

                string xmlFile = @"Resources\movies.xml";
                string moviesXml = System.IO.File.ReadAllText(xmlFile);
                XElement movies = XElement.Parse(moviesXml);

               TransformMovies(movies,body);

                wordDoc.MainDocumentPart.Document = doc;
                return File(mem, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");
            }

        }
 }

and below is the code for index.cshtml file

     @{
    Html.BeginForm("CreateDocument", "Home", FormMethod.Get);
    {
        <div>
            <input type="submit" value="Create Document" style="width:150px;height:27px" />
        </div>
    }
    Html.EndForm();
   }

i am not sure where i am doing wring with this code and i am using dot net core Would any one please let me know how can i avoid mentioned error and need to be able to download the word document when i click on button.

Many thanks in advance

stacktrace

ObjectDisposedException: Cannot access a closed Stream.
System.IO.MemoryStream.Read(byte[] buffer, int offset, int count)
System.IO.MemoryStream.ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
Microsoft.AspNetCore.Http.StreamCopyOperationInternal.CopyToAsync(Stream source, Stream destination, Nullable<long> count, int bufferSize, CancellationToken cancel)
Microsoft.AspNetCore.Mvc.Infrastructure.FileResultExecutorBase.WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue range, long rangeLength)
Microsoft.AspNetCore.Mvc.Infrastructure.FileStreamResultExecutor.ExecuteAsync(ActionContext context, FileStreamResult result)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|21_0(ResourceInvoker invoker, IActionResult result)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0<TFilter, TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter, TFilterAsync>(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Glory Raj
  • 17,397
  • 27
  • 100
  • 203
  • On what line of code are you seeing that exception originate? What does the stack look like? – Flydog57 Dec 30 '19 at 19:08
  • Does this answer your question? [Why am I getting "Cannot access a closed Stream" here?](https://stackoverflow.com/questions/36184509/why-am-i-getting-cannot-access-a-closed-stream-here) – Ryan Wilson Dec 30 '19 at 19:08
  • @Flydog57 i just added the stacktrace and the error i am getting at the closing bracket – Glory Raj Dec 30 '19 at 19:11

1 Answers1

2

You're returning mem from inside your using at which point it is disposed.

The "mem" variable inside this File() goes out of scope and is disposed as soon as you return it.

return File(mem, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");

E.g., in the below, Console.Writeline will throw a "Cannot access a closed Stream."

class Program
{
    static MemoryStream GetMemoryStream()
    {
        using (MemoryStream mem = new MemoryStream())
        {
            // BAD CODE - BUG!
            return mem;

            // The above will return an object which is about to be Disposed!
        }
    }
    static void Main(string[] args)
    {
        MemoryStream mem = GetMemoryStream();

        Console.WriteLine(mem.Length);
    }
}

Something like the below would work, this maintains the using incase a Exception is thrown above the return. You'll need to manually Dispose newMem at some point in the future if the return is successful.

        var newMem = new MemoryStream();
        mem.CopyTo(newMem);
        return File(newMem, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "ABC.docx");
Rowan Smith
  • 1,815
  • 15
  • 29