Write PDF Stream to Response Stream

Write PDF stream to response stream

Since you are using MVC, the best way is to use FileStreamResult:

return new FileStreamResult(stream, "application/pdf")
{
FileDownloadName = "file.pdf"
};

Playing with Response.Write or Response.OutputStream from your controller is non-idiomatic and there's no reason to write your own ActionResult when one already exists.

Trying to stream a PDF file with asp.net is producing a damaged file

Here is a method I use. This passes back an attachment, so IE produces an Open/Save dialog. I also happen to know that the files will not be larger than 1M, so I'm sure there's a cleaner way to do this.

I had a similar problem with PDFs, and I realized that I absolutely had to use Binary streams and ReadBytes. Anything with strings messed it up.

Stream stream = GetStream(); // Assuming you have a method that does this.
BinaryReader reader = new BinaryReader(stream);

HttpResponse response = HttpContext.Current.Response;
response.ContentType = "application/pdf";
response.AddHeader("Content-Disposition", "attachment; filename=file.pdf");
response.ClearContent();
response.OutputStream.Write(reader.ReadBytes(1000000), 0, 1000000);

// End the response to prevent further work by the page processor.
response.End();

How to assemble pdf from HTTP stream?

Is it your intention to save the file to the hardrive before sending it to the browser? Cause that is what you're (incorrectly) doing now.

Best is to enclose the write action in a using statement, cause I don't see you close the stream anywhere:

stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create);

Here you're saving to the file:

CopyStream(responseStream, stream);

Next, you're trying to read your outputstream (with which you just saved the file), to write that to your Response.Outputstream. And you have allready a copystream implementation, so why do it manually here? :

HttpContext.Current.Response.OutputStream.Write(buffer, 0, length);

So, I would say it should be something like:

using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
{
using (System.IO.Stream responseStream = httpResponse.GetResponseStream())
{
var filepath = @"C:\Users\David\Downloads\UberwriterUSRReport.pdf";
HttpContext.Current.Response.ContentType = "application/pdf";

// let the browser know how to open the PDF document, attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf"));

using (var stream = new System.IO.FileStream(filepath, System.IO.FileMode.Create)) {
CopyStream(responseStream, stream);
}

using (var readstream = new System.IO.FileStream(filepath, System.IO.FileMode.Read)) {
CopyStream(readstream, HttpContext.Current.Response.OutputStream);
}
}
}

Or, if you don't want to save the file on the server at all:

using (HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse())
{
using (System.IO.Stream responseStream = httpResponse.GetResponseStream())
{
// let the browser know how to open the PDF document, attachment or inline, and the file name
HttpContext.Current.Response.AddHeader("Content-Disposition", String.Format("attachment; filename=UberwriterUSRReport.pdf"));

CopyStream(responseStream, HttpContext.Current.Response.OutputStream);
}
}

Stream PDF to browser?

I've done this from a file on disk - sending the data from a memory stream shouldn't be that much different. You need to supply two pieces of metadata to the browser, in addition to the data itself. First you need to supply the MIME type of the data (in your case it would be application/pdf), then the size of the data in bytes (integer) in a Content-Length header, then send the data itself.

So in summary (taking into account the comments and what I think you're asking, your markup would look like this:

<asp:LinkButton ID="whatever" runat="server" OnClick="lnkButton_Click" 
OnClientClick="aspnetForm.target='_blank';">your link text</aspnet:LinkButton>

These few lines of C# code in your code behind should do the trick (more or less):

protected void lnkButton_Click(object sender, EventArgs e)
{
Response.ClearContent();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "inline; filename=" + docName);
Response.AddHeader("Content-Length", docSize.ToString());
Response.BinaryWrite((byte[])docStream);
Response.End();
}

Merging Memory Streams to create a http PDF response in c#

Here's a simple merge method that copies PDF files into one PDF. I use this method quite often when merging pdfs. Hope it helps.

    public MemoryStream MergePdfForms(List<byte[]> files)
{
if (files.Count > 1)
{
PdfReader pdfFile;
Document doc;
PdfWriter pCopy;
MemoryStream msOutput = new MemoryStream();

pdfFile = new PdfReader(files[0]);

doc = new Document();
pCopy = new PdfSmartCopy(doc, msOutput);

doc.Open();

for (int k = 0; k < files.Count; k++)
{
pdfFile = new PdfReader(files[k]);
for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
{
((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
}
pCopy.FreeReader(pdfFile);
}

pdfFile.Close();
pCopy.Close();
doc.Close();

return msOutput;
}
else if (files.Count == 1)
{
return new MemoryStream(files[0]);
}

return null;
}

Step 4 try:

        rptCS.Close();
rptCS.Dispose();
rptAd.Close();
rptAd.Dispose();

Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition",
"attachment; filename=" +
"Application of " + FullName.Trim() + ".pdf");
Response.BinaryWrite(ms.ToArray());
ApplicationInstance.CompleteRequest();


Related Topics



Leave a reply



Submit