2012-06-07 58 views
0

我正在編輯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後?

回答

3

最後兩個代碼的行之前返回的

newPdf = ms; 
formFiller.Close(); 

因爲你的代碼是全部using (MemoryStream ms = new MemoryStream())塊內,該MemoryStream MS將被關閉返回反正之前。

既然你要分配newPdf給變量ms,nwePdf eventualy返回相同的(已關閉)MemoryStreamms點。

你可以有public Stream GS(string ID, PdfReader reader)只創建而不使用塊流,但你如果在你的代碼中出現異常運行保持開放的風險。我想你可以嘗試以下方法:

// 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,因爲一個是簡單地在函數的開始申報,然後設置在最後指向其他沒有被用於其他任何事情。

更新:我找到了example using the PdfStamper。根據該示例,調用formFiller.Close()是實際寫入流的內容。在他們的示例中,他們不會將Writer.CloseStream屬性設置爲false。這可能就是爲什麼你會得到一個空白頁面。不幸的是,我無法找到任何關於PdfStamper的實際文檔來驗證這一點。

+0

我在做我認爲進展。我沒有錯誤,現在我只是有一個空白的新標籤... – MrM

+0

我發現一篇文章,顯示某人正在做你正在做的事情。在他們的例子中,他們沒有將'formFiller.Writer.CloseStream'設置爲false。試試看。 –

1

在您的代碼中,msnewPdf指的是相同的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; 
} 

我不是很熟悉ASP.NET MVC的,但我認爲FileStreamResult會關閉流的照顧。