I'm working on replacing a system that primarily uses PDF files to give users their monthly reports.
The problem I'm having is being able to prevent one user from seeing another's information. For example if user1 has a file at www.mysite.com/user1/file.pdf they could edit the URL to www.mysite.com/user2/file.pdf and see the files of user2.
The way I've been trying to get around this is to disable anonymous access (it's an IIS server) to the user folders so it's impossible to get direct access to files and have view_file.asp bring in the file using ADODB.Stream. I'm having a problem though that some users have not been able to view the files. It seems to only be people using IE but it's hard to be sure.
I basically just need to either fix this to work in all browser/configs or find an alternative way to display the file through the browser.
Set adoStream = CreateObject("ADODB.Stream")
adoStream.Type = 1
adoStream.Open()
adoStream.LoadFromFile "C:/path-to-file/" & curUser & curDir
Response.Buffer = true
Response.CharSet = "UTF-8"
Response.Clear
Response.ContentType = "application/pdf"
Do While Not adoStream.eos
Response.BinaryWrite adoStream.Read(1024 * 8)
Response.Flush
Loop
Response.End()
adoStream.close
Set adoStream=nothing
Related
I am at a loss here. I am trying to transmit a file on the local intranet site. When I get a download prompt in IE11, it says:
Do you want to open or save "SomePage.aspx?fileID=12345"? [open] [save] [cancel]
Instead of..
Do you want to open or save "Document.pdf"? [open] [save] [cancel]
It works perfectly fine on Chrome. The file gets downloaded with the correct filename. But for some reason, IE isn't setting the name and instead uses the ASPX name.
The code is rather straightforward:
testFile = New System.IO.FileInfo("\\someshare\somefolder$\Document.pdf")
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=" & testFile.Name)
Response.AddHeader("Content-Length", testFile.Length.ToString())
Response.ContentType = "application/octet-stream"
Response.TransmitFile(testFile.FullName)
I've tried a number of different header options and the MIME type makes no difference.
Does anyone have a clue why this would be happening?
Notes: Not HTTPS. It is not limited to PDF, same happens with .TIF, .DOC, and every other format I've tested.
EDIT: Have also tried Response.WriteFile as well as Response.BinaryWrite .. same thing each time.
EDIT2: Simplified everything down to a single button on a completely blank page.
You should have quote marks around the file name. See 19.5.1 on http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html
i.e.
Content-Disposition: attachment; filename="fname.ext"
so...
Response.AddHeader("Content-Disposition", String.Format("attachment; filename=""{0}""", testFile.Name))
Unfortunately I have not been able to test if this solves your issue as I don't have access to IE11 at the moment.
So I know this question is older, but the solution I finally came up with to this problem is to add the following two lines to my code.
Response.SuppressContent = True
and
HttpContext.Current.ApplicationInstance.CompleteRequest()
You have said in previous comments that you have tried the CompleteRequest command to no avail.
As a note, I am not 100% certain to the logistics of the Response.SuppressContent() command.
The documentation says that it indicates "whether to send HTTP content to the client". This seems counter intuitive to the process of sending the request body back to the client, however, it appears to only suppress the parts of the response that include any HTML.
It seems that the partial or incomplete HTML is what causes the filename to appear as the page name regardless of the headers set and sent. Stripping this out should cause the file to download properly.
Interestingly, this solution is actually born out of a secondary issue where once I was able to export the file using ClosedXML, i was receiving messages when opening the document that there were errors than excel would try to fix.
Response.SuppressContent actually fixed that as well. Hope this helps or at least points you in the right direction.
Using VBS in an ASP page or ASPNet page, I would like to determine the date when a remote web-based JPG file was created (or modified, etc). For example a webcam shot which was FTP-ed to the website. Thus, with the URL of the JPG, how can I get to the properties of that JPG.
In the code below I tried to retrieve the image file and save it into my site web, but I get an error on the "objADOStream.SaveToFile (strSave,2)" line which says that
"System.Runtime.InteropServices.COMException: Write to file failed.".
I know I have read/write permissions to that folder as I regularly create/delete .txt files there.
Can you comment on why I am not able to save this file?
Assuming I do get it saved will the original file properties be retained?
Or, maybe even better, is there an easier way to get this photo file information?
Here is the code that I cobbled together to retrieve and save the file
dim strURL, strSave, objXMLHTTP, objADOStream, objFSO
strURL = "http://www.somewhere.com/Photo.jpg"
strSave = Server.MapPath("/xxx/photos/") & "photo.jpg"
objXMLHTTP = CreateObject("MSXML2.XMLHTTP")
objXMLHTTP.open ("GET", strURL, false)
objXMLHTTP.send()
if err.number=0 then
if objXMLHTTP.readystate = 4 then
If objXMLHTTP.Status = 200 Then
objADOStream = CreateObject("ADODB.Stream")
objADOStream.Open
objADOStream.Type = 1
objADOStream.Write (objXMLHTTP.ResponseBody)
objADOStream.Position = 0
objFSO = Createobject("Scripting.FileSystemObject")
If objFSO.Fileexists(strSave) Then objFSO.DeleteFile (strSave)
objFSO = Nothing
objADOStream.SaveToFile (strSave,2)
objADOStream.Close
objADOStream = Nothing
End If
end if
end if
objXMLHTTP = Nothing
Thanks...RDK
If all you need is to know the last modification date of the file, instead of sending a GET request, send a HEAD request. In your code change GET with HEAD and, after send get
objXMLHTTP.getResponseHeader("Last-Modified")
It is possible that the server don't send this information, so you have no way to know this data.
I'm trying to create a pdf of the content on a page ("returnsPage.aspx?id="returnId) and allow the user to download this directly when clicking the button.
However in my onClick method I have the following code:
lnkLoadPDF.CommandArgument = "/returns/returnsPage.aspx?id="+returnId.ToString();
string virtualPath = lnkLoadPDF.CommandArgument;
string fileName = System.IO.Path.GetFileName(virtualPath);
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
Response.WriteFile(virtualPath);
Response.ContentType = "";
Response.End();
Response.Redirect("/returns/returnsPage.aspx?id="+returnId);
which returns this error:
'/returns/returnsPage.aspx?id=23' is not a valid virtual path.
Can anyone please tell me what I'm doing wrong?
Thanks!
In order to turn a webpage into a pdf, you must convert it to pdf on the server. In order to do that, you must have a program on the server that can do that for you.
I've tried a variety of webpage-to-pdf converters and one of the better ones is a free, open source program called wkhtmltopdf.
After you create the pdf, you can either redirect the user to the newly created pdf (discouraged), or prompt them to download it with a savefile dialog.
If you get stuck, just search for wkhtmltopdf on stackoverflow or post another question.
You can't send a file to the client and redirect him to a new location during the same request. You also can't create a PDF from a webpage without some kind of component that converts the HTML into a PDF, it's (quite a bit) more tricky that what I think you're trying to attempt.
As for your exception, are you sure returnsPage.aspx exists? :)
Current situation
I have ASP.NET web application that render PDF for users using MS Report Viewer. The PDF is rendered with this method:
Byte pdfByte = Byte();
pdfByte = ReportViewer.LocalReport.Render("PDF", Nothing, mimeType, encoding, extensions, stream, warning)
And send to browser as an attachment with response object:
Response.Clear()
Response.ContentType = mimeType
Response.AddHeader("content-disposition", "attachment; filename=myfile." + extension)
Response.BinaryWrite(pdfByte)
Response.Flush()
Response.End()
This work great! The user browser will get the PDF as download-able attachment.
What I am trying to achieve
Render multiple PDF and send all of them separately to user's browser. User will get separate PDF documents. It doesn't matter whether they will get them all at once or one by one.
The problem
The problem is after Response.End() the next line of code is not executed. I have tried to store the pdfByte object in session, looping through it and send them to user's browser with Response object but after the first PDF get sent then it stop.
I have also tried removing Response.End() thinking the code will keep running but still it stop after the first PDF get sent.
Please advice any workaround or tips. Thanks!
You cannot send multiple files (as separate entities) in a single HTTP response (the protocol does not support it. However, what you can do is to archive all files together and send the that single zip (or whatever format you want) to the client.
You can use libraries such as DotNetZip/SharpZipLib to combine (and compress) files together. Based on library API, you may need to save PDF files to disk before adding to zip file. Also do not forget to change your content type appropriate while sending the zip file to client.
Yet another alternative is to provide user with a page having multiple links to download files. It may mean that you either have to store your PDFs for some time so that they can served later (via links) or make link point to a handler that will re-run the report again to get the PDF out of it.
Admittedly the method I'm using doesn't feel very elegant, but here's what I'm doing:
create one IFRAME on the page for each document you want to send to the client (maybe create the IFRAMEs dynamically in server-side code if the number of documents is variable);
create a HttpHandler that generates the PDF documents, depending on a parameter you're passing in through the QueryString, just like you're doing above;
set the src on all IFRAMES to the URL of the HttpHandler with the appropriate parameters attached.
Of course the HttpHandler needs to do implement security logic, if required.
This works quite beautifully: If I want to send 3 documents, I create 3 IFRAMEs, set their src, and the user will see 3 "Save As..." dialogs pop up.
Pardon the dumb newbie question here; web programming isn't my forte... (blush)
I have an aspx page running on a web server. I have a blob (byte array) containing any kind of binary file, plus a file name.
I would like to push this file to be downloaded through the browser onto the client, and opened using whatever application is default for this file type. I really don't want to save the blob as a file on the server; that will leave a terrible housekeeping mess that I just don't want to think about.
I did try googling this question, but I guess I'm using the wrong keywords.
This really should be obvious how to do it, but I'm having no joy.
What is the trick?
Thanks!
Response.BinaryWrite(byteArray);
You should also set the content type
Response.ContentType = "application/pdf";
But that will be based on your file type.
And the file name (and everything together) is done like this
Response.AddHeader("content-disposition",
String.Format("attachment;filename={0}", fileName));
Response.ContentType = "application/pdf";
Response.BinaryWrite(byteArray);
First, you have to know the mime type. Once you know that, you can set the Response.ContentType property. After that, just use Response.BinaryWrite(). If you don't first set the ContentType property, the client will have almost no chance of opening the file correctly.