スタックトレースは次のようになります
[ObjectDisposedException:閉じたストリームにアクセスできません。]
System.IO .__ Error.StreamIsClosed()+53
System.IO.MemoryStream.Read(Byte [] buffer、Int32 offset、Int32 count)+11411219 System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase response)+81 System.Web.Mvc.FileResult.ExecuteResult (ControllerContextコンテキスト)+168
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext、ActionResult actionResult)+13
呼び出した後
//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");
}
私は読みました MemoryStream-閉じたストリームにアクセスできません ですが、StreamReader
を使用していないため、同じシナリオではありません
編集:まだ機能していません
[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;
}
}
アクションメソッドまたはusing ( var ms = new MemoryStream() ) {
ブロックを終了するとすぐにストリームが閉じられました。
MemoryStreamを破棄する必要はありません。 File(ms, "application/pdf", "Test.pdf");
によって返されるFileStreamResultオブジェクトは レンダリング後に破棄 します。実際にストリームデータを送信するコードは次のとおりです。
_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);
}
}
_
あなたはこれをブロックを使って置き換えることができます:
_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;
}
_
エラーが発生した場合にストリームが確実に破棄されるようにします。
[〜#〜]更新[〜#〜]
Igorが述べたように、そしてソースコードが示すように、FileStreamResultはストリームの位置をリセットしません。 return File(...)
を呼び出す前に0に設定する必要があります
PdfWriter
クラスがストリームを閉じている可能性があります。 CloseStream
プロパティを必ずfalseに設定してください。
次に、using
アクションの結果は次のようになるので、ここでMemoryStream
に対してFileStreamResult
をしないでください送信後のストリームの破棄に注意してください。現在、ストリームは送信が行われる前に(破棄によって)実際に閉じられています。
また、ファイルを送信する前に、ストリームを位置0に戻す必要があります。
全体をtry...catch
ただし、エラーが発生した場合にストリームを破棄します(ただし、最終的にはGCが処理し、適切に管理されている場合はMemoryStream
になるため、必須ではありません)。