如何保持从模型到控制器的流打开
本文关键字:控制器 何保持 模型 | 更新日期: 2023-09-27 18:36:27
>我正在编辑一个pdf,然后在新选项卡中打印。我收到一条错误消息,指出我"无法访问已关闭的流"。这就是我到目前为止所拥有的...
控制器
public ActionResult QST(string ID)
{
...
PdfReader reader = new PdfReader(Server.MapPath("~/Content/PDF/QST.pdf"));
QstRepository repo = new QstRepository();
Stream newPdf = repo.GS(ID, reader);
return new FileStreamResult(newPdf, "application/pdf");
}
型
public Stream GS(string ID, PdfReader reader)
{
Stream newPdf = new MemoryStream();
using (MemoryStream ms = new MemoryStream())
{
PdfStamper formFiller = new PdfStamper(reader, ms);
AcroFields formFields = formFiller.AcroFields;
formFields.SetField("ID", ID);
formFiller.FormFlattening = true;
formFiller.Writer.CloseStream = false;
newPdf = ms;
formFiller.Close();
}
return newPdf;
}
如何在关闭之前访问 pdf...或者之后如何访问 PDF?
返回之前代码的最后两行是
newPdf = ms;
formFiller.Close();
由于您的代码都在using (MemoryStream ms = new MemoryStream())
块中,因此无论如何,MemoryStream
ms都将在您返回之前关闭。
由于您将newPdf
分配给变量ms
,nwePdf finalualy 返回与ms
指向的相同(已关闭)MemoryStream
。
您可能public Stream GS(string ID, PdfReader reader)
创建流而不使用 using 块,但如果代码中发生异常,您将面临它保持打开状态的风险。 我想您可以尝试以下方法:
// All calls to GS() must ensure that the returned stream gets closed.
public Stream GS(string ID, PdfReader reader)
{
MemoryStream newPdf = new MemoryStream();
PdfStamper formFiller = null;
try
{
formFiller = new PdfStamper(reader, newPdf);
AcroFields formFields = formFiller.AcroFields;
formFields.SetField("ID", ID);
formFiller.FormFlattening = true;
//formFiller.Writer.CloseStream = false;
}
catch
{
// Only close newPdf on an exception
newPdf.Close();
throw; // Rethrow original exception
}
finally
{
// Always ensure that formFiller gets closed
formFiller.Close();
}
return newPdf;
}
更新:我删除了额外的 MemoryStream,因为一个只是在函数的开头声明,然后在末尾设置为指向另一个,而从未用于两者之间的任何其他内容。
更新:我找到了一个使用PdfStamper的示例。 根据该示例,调用formFiller.Close()是实际写入流的内容。 在他们的示例中,他们没有将 Writer.CloseStream 属性设置为 false。 这可能就是你得到一个空白页的原因。 不幸的是,我无法在PdfStamper上找到任何实际文档来验证这一点。
在你的代码中,ms
和 newPdf
引用同一个MemoryStream
实例;由于ms
在using
块的末尾关闭,newPdf
也是关闭的(因为它是同一个流)。因此,您需要在不关闭Stream
的情况下返回它:
public Stream GS(string ID, PdfReader reader)
{
PdfStamper formFiller = new PdfStamper(reader, ms);
AcroFields formFields = formFiller.AcroFields;
formFields.SetField("ID", ID);
formFiller.FormFlattening = true;
formFiller.Writer.CloseStream = false;
formFiller.Close();
return ms;
}
我对 MVC 不是很熟悉 ASP.NET 但我认为FileStreamResult
负责关闭流。