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
How to Calculate the Average Rgb Color Values of a Bitmap
Count Number of Mondays in a Given Date Range
Wpf Binding - Default Value for Empty String
How to Dynamically Switch Web Service Addresses in .Net Without a Recompile
How to Detect Which .Net Runtime Is Being Used (Ms VS. Mono)
Sorting an Array Related to Another Array
C# Linq Intersect/Except with One Part of Object
Is That Possible to Send Httpwebrequest Using Tls1.2 on .Net 4.0 Framework
Getting the Index of a Particular Item in Array
Task.Factory.Startnew with Async Lambda and Task.Waitall
How to Check If Thread Finished Execution
Equivalent Code of Createobject in C#
Writing to Then Reading from a Memorystream
Why Won't Anyone Accept Public Fields in C#