C# 如何保持从模型到控制器的流是开放的?

C# 如何保持从模型到控制器的流是开放的?,c#,asp.net-mvc,pdf,C#,Asp.net Mvc,Pdf,我正在编辑pdf,然后在新选项卡中打印。我得到一个错误,说我“无法访问一个封闭的流”。这是我到目前为止 控制器 public ActionResult QST(string ID) { ... PdfReader reader = new PdfReader(Server.MapPath("~/Content/PDF/QST.pdf")); QstRepository repo = new QstRepository(); Stream newPdf =

我正在编辑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");
}
模型


如何在pdf关闭之前访问它。。。或者如何在返回后访问pdf?

返回前的最后两行代码是

newPdf = ms;
formFiller.Close(); 
由于您的代码都在
使用(MemoryStream ms=new MemoryStream())
块的
中,因此在您返回之前,
MemoryStream
ms将被关闭

由于将
newPdf
赋值给变量
ms
,nwePdf最终返回
ms
指向的相同(已关闭的)
MemoryStream

您可以使用
公共流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,因为在函数开始时只声明了一个,然后在函数结束时设置为指向另一个,而不用于其间的任何其他内容


更新:我找到了一个。根据该示例,调用formFiller.Close()实际上是写入流的操作。在他们的示例中,他们没有将Writer.CloseStream属性设置为false。这可能就是为什么你会得到一张空白页。不幸的是,我无法找到任何关于PdfStamper的实际文档来验证这一点。

返回前的最后两行代码是

newPdf = ms;
formFiller.Close(); 
由于您的代码都在
使用(MemoryStream ms=new MemoryStream())
块的
中,因此在您返回之前,
MemoryStream
ms将被关闭

由于将
newPdf
赋值给变量
ms
,nwePdf最终返回
ms
指向的相同(已关闭的)
MemoryStream

您可以使用
公共流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,因为在函数开始时只声明了一个,然后在函数结束时设置为指向另一个,而不用于其间的任何其他内容


更新:我找到了一个。根据该示例,调用formFiller.Close()实际上是写入流的操作。在他们的示例中,他们没有将Writer.CloseStream属性设置为false。这可能就是为什么你会得到一张空白页。不幸的是,我无法找到任何关于PdfStamper的实际文档来验证这一点。

在您的代码中,
ms
newPdf
引用了相同的
MemoryStream
实例;由于
ms
使用
块结束时关闭,
newPdf
也关闭(因为它是相同的流)。因此,您需要返回
,而不关闭它:

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;
}

我不太熟悉ASP.NET MVC,但我假设
FileStreamResult
负责关闭流。

在您的代码中,
ms
newPdf
引用相同的
MemoryStream
实例;由于
ms
使用
块结束时关闭,
newPdf
也关闭(因为它是相同的流)。因此,您需要返回
,而不关闭它:

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;
}

我不太熟悉ASP.NET MVC,但我认为
FileStreamResult
负责关闭流。

我认为我正在取得进展。我没有错误,现在我只有一个空白的新标签…我发现一篇文章,显示某人正在做你正试图做的事情。在他们的示例中,他们没有将
formFiller.Writer.CloseStream
设置为false。试试看,我想我正在进步。我没有错误,现在我只有一个空白的新标签…我发现一篇文章,显示某人正在做你正试图做的事情。在他们的示例中,他们没有将
formFiller.Writer.CloseStream
设置为false。试试看。