2016-03-23 77 views
6

Stack trace sembraPerché sto ottenendo "Impossibile accedere a un flusso chiuso" qui?

[ObjectDisposedException: Impossibile accedere un flusso chiuso.]
System.IO .__ Error.StreamIsClosed() +53
System.IO.MemoryStream.Read (Byte [] tampone, Int32 Offset, conteggio Int32) 11.411.219 System.Web.Mvc.FileStreamResult.WriteFile (HttpResponseBase risposta) +81 System.Web.Mvc.FileResult.ExecuteResult (contesto ControllerContext) 168
System.Web.Mvc.ControllerActionInvoker. InvokeActionResult (ControllerContext controllerContext, ActionResult actionResult) +13

dopo aver richiamato

 //Byte[] bytes; 
     using (var ms = new MemoryStream()) 
     { 
      using (var doc = new Document()) 
      { 
       using (var writer = PdfWriter.GetInstance(doc, ms)) 
       { 

        doc.Open(); 
        //var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!!!</span></p>"; 
        var example_html = System.IO.File.ReadAllText(Path.Combine(Server.MapPath("~/EmailTemplates"), "template.html")); 
        var example_css = @".headline{font-size:200%}"; 
        using (var srHtml = new StringReader(example_html)) 
        { 
         iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml); 
        } 
        using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css))) 
        { 
         using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html))) 
         { 
          iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss); 
         } 
        } 


        doc.Close(); 
       } 
      } 
      //bytes = ms.ToArray(); 
      return File(ms, "application/pdf", "Test.pdf"); 
     } 

ho letto MemoryStream - Cannot access a closed Stream, ma non è lo stesso scenario, perché non sto usando StreamReader

Edit: Ancora non funziona con

[OutputCache(NoStore = true, Duration = 0)] 
    public ActionResult Run() 
    { 
     Byte[] bytes; 
     var ms = new MemoryStream(); 
     try 
     { 
      using (var doc = new Document()) 
      { 
       using (var writer = PdfWriter.GetInstance(doc, ms)) 
       { 
        writer.CloseStream = false; 
        doc.Open(); 
        var example_html = @"<p>This <em>is </em><span class=""headline"" style=""text-decoration: underline;"">some</span> <strong>sample <em> text</em></strong><span style=""color: red;"">!!!</span></p>"; 
        //var example_html = System.IO.File.ReadAllText(Path.Combine(Server.MapPath("~/EmailTemplates"), "LinkEmailTemplate.html")); 
        var example_css = @".headline{font-size:200%}"; 
        using (var msCss = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_css))) 
        { 
         using (var msHtml = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(example_html))) 
         { 
          iTextSharp.tool.xml.XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, msHtml, msCss); 
         } 
        } 
        doc.Close(); 
       } 
      } 
      bytes = ms.ToArray(); 
      ms.Position = 0; 
      return File(ms, "application/pdf", "Test.pdf"); 
     } 
     catch 
     { 
      ms.Dispose(); 
      throw; 
     }   
    } 
+1

Perché lo stream è stato chiuso non appena sei uscito dal metodo di azione. Quando la vista ha tentato di accedervi, ha scoperto che era già chiusa. –

+1

'Ancora non funziona con' - define 'not working'. Inoltre hai una variabile chiamata 'bytes' che non fa nulla ma sono curioso di sapere se c'è qualcosa in questo array prima che il tuo metodo esca. – Igor

+2

* Perché * si copia il contenuto del flusso in un array di byte? Se lo fai, non c'è motivo di restituire * stream * con 'File (..)', basta restituire l'array di byte es. 'File (byte ...)' –

risposta

0

La classe PdfWriter potrebbe chiuderti r flusso. Assicurati di impostare la proprietà CloseStream su false.

Si dovrebbe poi non utilizzare using sul MemoryStream qui, dal momento che il risultato FileStreamResult azione si occuperà dello smaltimento del flusso dopo l'invio fuori. In questo momento lo streaming è effettivamente chiuso (da disporre) prima che l'invio abbia luogo.

Inoltre, è necessario cercare lo stream di nuovo in posizione 0 prima di inviare il file.

si può avvolgere la parte intera in un try...catch comunque di smaltire il flusso in caso di errore (ma il GC avrebbe finalmente prendersi cura di esso e MemoryStream se Sully gestito, in modo che non è obbligatorio).

+0

'Document' è' iTextSharp.Text.Document' –

6

Lo stream è stato chiuso non appena si è usciti dal metodo di azione, ovvero il blocco using (var ms = new MemoryStream()) {.

Non è necessario disporre di MemoryStream. L'oggetto FileStreamResult restituito da File(ms, "application/pdf", "Test.pdf"); sarà dispose it after rendering. Il codice che invia effettivamente il flusso di dati è:

protected async override Task WriteFileAsync(HttpResponse response) 
{ 
    var outputStream = response.Body; 

    using (FileStream) 
    { 
     var bufferingFeature = response.HttpContext.Features.Get<IHttpBufferingFeature>(); 
     bufferingFeature?.DisableResponseBuffering(); 

     await FileStream.CopyToAsync(outputStream, BufferSize); 
    } 
} 

è possibile sostituire questo blocco utilizzando con:

var ms = new MemoryStream(); 
try 
{ 
    //.. 
    //From Igor's comment. FileStreamResult won't reset the stream position itself 
    ms.Position=0; 
    return File(ms, "application/pdf", "Test.pdf"); 
} 
catch 
{ 
    ms.Dispose(); 
    throw; 
} 

per garantire che il flusso venga disposta se si verifica un errore.

UPDATE

Come detto Igor, e come mostra il codice sorgente, FileStreamResult non ripristinare la posizione di flusso. Dovrai impostarlo su 0 prima di chiamare return File(...)

+1

Probabilmente vorrete anche ripristinare la posizione nel flusso di memoria prima di passarla a File. 'ms.Position = 0;' – Igor

+0

Grazie, aggiornato –

+0

C'è qualcos'altro che potrei mancare? Ho intenzione di incollare il mio codice di aggiornamento sopra –

Problemi correlati