Present a PDF Document on a Specific Page in ASP.NET - asp.net

I am opening PDF documents using the following ASP.NET code,
Response.BufferOutput = true;
Response.Clear();
Response.ContentType = "application/pdf";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(documentURL);
using (HttpWebResponse responseDDRINT = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = responseDDRINT.GetResponseStream())
{
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, bufferSize)) > 0)
{
Response.OutputStream.Write(buffer, 0, bytesRead);
}
Response.Flush();
}
}
My question is does anyone know how to present the PDF starting at a specifice page. For example, if the PDF document is 15 pages, we would like it to open with page 10 initially showing instead of opening at page 1.
I experimented with the "#page=" open parameter by adding this header, but it did nothing.
Response.AddHeader("content-disposition", "inline; filename=test.pdf#page=3");

You'll have to manipulate the PDF file on the fly.
Use something like http://pdfsharp.com/PDFsharp/ to stream out a copy of the file starting at a certain page.

Current versions of Adobe ready no longer support the page syntax, but they do support the bookmark syntax.
Why don't you make your document reachable through a regular link or through an HTTPHandler?

you may use a PDF manipulation library like ItextSharp to get your work done.

Related

Pdf file damaged on download in Chrome and Firefox

I am using iTextSharp for creating pdf reports (files) and storing those on the web server where my application resides. I am able to create the file, go into the storage folder and open the file without a problem. Notice: The user is not to get the file automatically
downloaded on creation.
I want to give the user the option to download "old" reports from the server with a button.
This is working fine in IE (10) but not in Chrome and Firefox. I always get the error message:
There was an error opening this document. The file is damaged and could not be repaired.
I have this image button and on click I send the user to a Generic Handler (since my page contains Update Panels) according to this post (only using it partially for now).
This is the code that actually downloads the file:
public void ProcessRequest(HttpContext context)
{
var _fileName = context.Request.QueryString["fileName"];
using (var _output = new MemoryStream())
{
//var _fileSeverPath = context.Server.MapPath(_fileName);
context.Response.Clear();
context.Response.ContentType = "application/pdf";// "application/pdf";
//context.Response.AppendHeader("Content-Length", _fileName.Length.ToString());
context.Response.AppendHeader("Content-Disposition", string.Format("attachment; filename=" + Path.GetFileName(_fileName)));
context.Response.WriteFile(_fileName);
context.Response.Flush();
context.Response.Close();
context.Response.End();
}
}
As I said, this works fine in IE but not in Chrome and Firefox.
When I open the file in Notepad it seams that I only get about 1/3 of the file when downloaded in Chrome and Firefox.
Any suggestions would be greatly appreciated. Been trying to resolve this for a few days now..
From HttpResponse.WriteFile Method (String)
When this method is used with large files, calling the method might
throw an exception. The size of the file that can be used with this
method depends on the hardware configuration of the Web server. For
more information, see article 812406, "PRB: Response.WriteFile Cannot
Download a Large File" on the Microsoft Knowledge Base Web site.
Try this instead:
public void ProcessRequest(HttpContext context)
{
var _fileName = context.Request.QueryString["fileName"];
context.Response.Clear();
context.Response.Buffer = true;
context.Response.ContentType = "application/pdf";
context.Response.AppendHeader(
"Content-Disposition",
string.Format("attachment; filename=" + Path.GetFileName(_fileName)));
using (var fs = new FileStream(_fileName, FileMode.Open, FileAccess.Read))
{
using (var sr = new StreamReader(fs, true))
{
int length = (int)fs.Length;
byte[] buffer;
using (BinaryReader br = new BinaryReader(fs, sr.CurrentEncoding))
{
buffer = br.ReadBytes(length);
context.Response.BinaryWrite(buffer);
}
}
}
context.Response.Flush();
context.Response.Close();
context.Response.End();
}
Ok, FINALLY.. I found the solution and it makes me feel like a fool at the same time..
Removed context.Response.Close(); ...then everything worked perfectly :)

Progressive streaming of video in asp.net

I want to do progressive streaming of video in asp.net. I have written a code for that but still its not loading properly. Does any have idea about it.
Please have look into my code or suggest me the best way to do it. I don't want player to wait for downloading whole video and then start playing. I want to start playing right now.
Following is my code.
string path = "Test.mp4";
string rootpath = Server.MapPath(Request.ApplicationPath);
string file = string.Format(#"{0}\\{1}", rootpath, path);
if (File.Exists(file) && file.Contains("mp4"))
{
FileStream filestream = new FileStream(file, FileMode.Open, FileAccess.Read);
long length = filestream.Length;
Response.AppendHeader("Content-Type", "video/mp4");
Response.AddHeader("Content-Disposition", "attachment; filename=" + path + "");
Response.AppendHeader("Content-Length", length.ToString());
const int buffersize = 16384;
byte[] buffer = new byte[buffersize];
int count = filestream.Read(buffer, 0, buffersize);
while (count > 0)
{
if (!Response.IsClientConnected)
count = -1;
else
{
Response.OutputStream.Write(buffer, 0, count);
Response.Flush();
count = filestream.Read(buffer, 0, buffersize);
}
}
}
Best Regards,
Jalpesh
I had the same problem and ended up implementing 'Range-Specific Request'. Check this article on dotNetSlackers. It has sample code for streaming of MP4 files. This solution works great on iPad, iPhone and Chrome!
The Content-Disposition header is used to instruct the browser to offer a Save As dialog for the attached file. probably not the behavior you want. Did you try removing it?

How to get file size of multiple file download

I am writing an ASP.NET web application.
I calculate the total size of my PDF file which is mentioned below. What does this return? When I download a 2KB file, it returns a size of 2KB, which is correct. But when I download 2 files each of size 2KB, then the total size it returns is 2.16KB. Is that correct? Should it return 4KB?
StringReader reader = new StringReader(content);
MemoryStream ms = new MemoryStream();
Document doc = new Document(PageSize.A4, 50, 50, 30, 30);
HTMLWorker parser = new HTMLWorker(doc);
PdfWriter.GetInstance(doc, ms);
doc.Open();
try
{
parser.Parse(reader);
}
catch (Exception ex)
{
Paragraph paragraph = new Paragraph("Error! " + ex.Message);
paragraph.SetAlignment("center");
Chunk text = paragraph.Chunks[0] as Chunk;
if (text != null)
{
//text.Font.Color = iTextSharp.text.BaseColor.RED;
}
doc.Add(paragraph);
}
finally
{
doc.SetMargins(10, 10, 10, 10);
doc.Close();
}
Byte[] buffer = ms.GetBuffer();
if (buffer != null)
{
Response.ContentType = "application/pdf";
Response.AppendHeader("content-disposition", "attachment;filename=FileName.pdf");
//Response.AddHeader("content-length", buffer.Length.ToString());
Response.BinaryWrite(buffer);
}
Sounds like you're opening two files into the same buffer and expecting them to be appended one to the other. Instead, the second is replacing the first.
Try all this stand-alone in a simple C# program. If it doesn't work there, it clearly won't work in an ASP page. OTOH, if it does work there, but not in ASP, then its an ASP issue, not a problem with iTextSharp.
PS: I thought doc.close would close the stream used by PdfWriter as well. Looking at the code, it will by default (protected boolean closeStream = true; from the java source). Something might have called setCloseStream(false) somewhere along the line.
PPS: Stacking two PDFs into the same binary stream is Not A Good Idea. You need to write them out as separate attachments... at which point this whole issue is moot.

asp.net ashx handler prompting download instead of displaying file

I implemented a generic handler in my application which works great for images, but when I manually type the handler URL in the browser with the image's querystring it prompts download instead of displaying. Here is my code:
public void ProcessRequest(HttpContext context)
{
if (this.FileName != null)
{
string path = Path.Combine(ConfigurationManager.UploadsDirectory, this.FileName);
if (File.Exists(path) == true)
{
FileStream file = new FileStream(path, FileMode.Open);
byte[] buffer = new byte[(int)file.Length];
file.Read(buffer, 0, (int)file.Length);
file.Close();
context.Response.ContentType = "application/octet-stream";
context.Response.AddHeader("content-disposition", "attachment; filename=\"" + this.FileName + "\"");
context.Response.BinaryWrite(buffer);
context.Response.End();
}
}
}
I am using the octet-stream because I'm dealing with more than just images and I don't always know the content type of the file. Thanks in advance!
The only way is to specify correct ContentType so the browser know what to do with receiving file, depending on installed plugins (for example, view pdf files in browser frame) and system assosiations (for example, offer to open document in MS Office instead of simple download)
You can try to specify Content Type depending on file extension, i.e.:
if(Path.GetExtension(path) == ".jpg")
context.Response.ContentType = "image/jpeg";
else
context.Response.ContentType = "application/octet-stream";
If you store the ContentType as part of the files metadata, when you pull it back down your could use it.
theFile = GetFile(id)
context.Response.ContentType = theFile.Type;
The content-disposition header is the one that causes your browser to show the download dialog. Remove that line and it will show in the browser.

How open byte[] into adobe format?

I has image into byte[]. I need to open it into adobe file in asp.net. I using following code :
byte[] bytes = contractimage.Value.Bytes;
if (bytes == null)
{
Response.Write("Not found.");
Response.End();
}
else
{
Response.AddHeader("content-disposition",
"attachment;filename=statement" + contractGuid.ToString() + ".pdf");
Response.ContentType = "application/pdf";
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.End();
}
But this code display an error that adobe canot dispalay this file it may be corrupted.
Please suggest
A byte[] of a bitmap is not a pdf document.
What you need to do is create a pdf doc that contains your Bitmap. If I were in your shoes I would probably use something like ITextSharp to do that.
You would have to format your output in the form of a PDF file, you are currently only sending the raw image data and not a properly formated PDF file.
You can refer to:
http://www.adobe.com/devnet/pdf/pdf_reference.html
for a specification of the PDF format or an easier solution is to use a third-party tool to accomplish your task.
Try a Google search for something like "pdf .net creator"

Resources