I require some assistance, I have a pdf file that is located on a ftp location.
What i want to do, is on a button click i want to retrieve the pdf file and display it on a new tab.
Please assist on how to accomplish this task.
Thanks in advance.
One approach would be to make a web request to download the file and then pass the download stream along to the ASP.NET response stream. I haven't compiled or executed this code, but it might look something like this:
WebRequest request = HttpWebRequest.Create("ftp://ftp.yoursite.com/yourfile.pdf");
request.Credentials = new NetworkCredential("ftpuser","ftppassword");
// Get the response
WebResponse response = request.GetResponse();
StreamReader responseStream = new StreamReader(response.GetResponseStream());
// Send the response directly to output
Response.ContentEncoding = responseStream.CurrentEncoding;
Response.ContentType = "application/pdf";
Response.Write(responseStream.ReadToEnd());
Response.End();
Just use the HTML anchor tag ("a" tag). In the href attribute put the FTP address of the PDF file (eg. ftp://example.com/file.pdf). To open in a new window you should also specify a target attribute with the value "_blank".
Example:
<a href='ftp://example.com/file.pdf' target='_blank'>Click here to open the PDF file</a>
When using HttpWebRequest to submit xml post data to a remote server, it inserts exclamation marks throughout the xml data when it sends it, causing the SOAP server to reject it and abort the connection. I have a HTML form submitter and it submits the xml in a textarea just fine without errors.
Here is my basic page logic for submitting the xml data, I have tried using the byte array as well but got the same errors.
Dim submitPage As HttpWebRequest = WebRequest.Create(requestUrl)
submitPage.Method = "POST"
Dim postData As StringBuilder = New StringBuilder()
postData.Append("Submit+XML=Submit&xmldata=" & System.Web.HttpUtility.UrlEncode(CompiledXML))
Dim writer As StreamWriter = Nothing
submitPage.ContentLength = postData.ToString().Length
writer = New StreamWriter(submitPage.GetRequestStream())
writer.Write(postData.ToString())
writer.Close()
So what happens here is is takes my XML string and puts it in the post but it also puts in exclamation marks about every 10 lines.
I have been working on this problem a couple days with no luck.
This was a bug in PHP on the remote server, where if you had a string over a certain length and you stuff it into the email function without line breaks it puts in exclamation points for you. Very odd behaviour but that was what was happening here.
I know this must be a rookie question, but how do i accomplish that?
Because from what i have seen here : http://msdn.microsoft.com/en-us/library/system.io.streamwriter or at XMLWriter is not helping me, because i just want to save all, not write specific lines.
Basically i have an httpRequest that returns back an XML response. I am getting that in a stream, and from that i want to save it to an xml file, for later use.
Part of the code:
HttpWebResponse response = (HttpWebResponse)httpRequest.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
XDocument blabla = XDocument.Parse(responseString);
// Here is where the saving to a file should occur
streamResponse.Close();
streamRead.Close();
Why do you need to parse the file? In .NET 4 you can just write it directly to disk using a file stream like this:
using (var fileStream = File.Create("file.xml"))
{
streamResponse.CopyTo(fileStream);
}
If you are using an earlier version of the .NET framework, you can use the method described here to copy data from one stream to another.
Have a look at this:
http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.save.aspx
Should help you get the job done!
As you already have the XML response as a string, I think what you need is to use a StreamWriter class to write the response string straight to a file.
There is an MSDN example of its use here: How to: Write Text to a File
I think it's possible with jQuery, but any ASP.NET serverside code is good for my situation too.
With jQuery I can load a page to for example a div, and filter the div for <title> tag, but I think for heavy pages, it is not good to first read all of the content and then read the title tag..
or maybe it has a very simple solution? anyways I couldnt find anything about that from internet.
thanks
okay thanks to cjjer and Boo, I've just read more about regex and finally the code below is working for me.
Dim qq As New System.Net.WebClient
Dim theuri As New Uri(TextBox1.Text)
Dim res As String = qq.DownloadString(theuri)
Dim re As Regex = New Regex("<title\b[^>]*>(.*?)</title>", RegexOptions.Singleline)
Dim ma As Match = re.Match(res)
If Not ma Is Nothing And ma.Success Then
Response.Write(ma.Groups(1).Value.ToString())
Else
Response.Write("error")
End If
but anyways, the problem remains, this code is downloading the whole page and seeking through it, which one heavy websites it took more than 2 or 3 secconds to complete, but seems it is the only way as far as I know :|
Is there any suggestions to refine this code?
cjjer almost got it right.
First, change the regex to: <title>(?<Content>.*?)?</title>
Second, you need to create a match object first (just in case your URI does not have a title).
Match tMatch = new RegEx(#"<title>(?<Content>.*?)?</title>").Match(new System.Net.WebClient().DownloadString(url));
if ((null != tMatch) && (tMatch.IsSuccess)) {
// yay.
title = tMatch.Groups("Content").value;
}
Titles usually appear within the first few hundred bytes, so you could try a range request for the first 1KiB or so, try parsing that (with an error-correcting parser, since some closing tags will be missing) and if that fails fall back to loading the whole page.
It would be security risk for you to load any other web page into yours, just for title read... You should do this with server side scripting (asp.net, php, ...) and just output the title to your web page. Thing of some kind of caching because it is seamless to fetch titles on every request.
There is no simple clean way to retrieve an external page's title. You could do it server side using a WebClient and parsing the response.
However it may be worth reviewing the requirement, is it really necessary, how much extra traffic and latency is it going to generate. Consider also that you could be generating load on the external site which is unaware all you want is a title, the page creation may be quite expensive.
string title=Regex.Match(new System.Net.WebClient().DownloadString(url),(#"<title>(.*?)</title>"))[0].Groups[1].ToString();
try.i am not sure.
I am not sure whether all servers support this.
See, if this helps
char[] data = new char[299];
System.Net.HttpWebRequest wr =(HttpWebRequest)WebRequest.Create("http://www.yahoo.com");
wr.AddRange("bytes", 0, 299);
HttpWebResponse wre = (HttpWebResponse)wr.GetResponse();
StreamReader sr = new StreamReader(wre.GetResponseStream());
sr.Read(data, 0, 299);
Console.WriteLine((data));
sr.Close();
EDIT: Try checking with some network monitoring tool to find out what is the text that servers send out. I used fiddler to see the output & wrote it to console.
EDIT2: I am assuming the title to be in the beginning of the page.
My app generates PDFs for user consumption. The "Content-Disposition" http header is set as mentioned here. This is set to "inline; filename=foo.pdf", which should be enough for Acrobat to give "foo.pdf" as the filename when saving the pdf.
However, upon clicking the "Save" button in the browser-embedded Acrobat, the default name to save is not that filename but instead the URL with slashes changed to underscores. Huge and ugly. Is there a way to affect this default filename in Adobe?
There IS a query string in the URLs, and this is non-negotiable. This may be significant, but adding a "&foo=/title.pdf" to the end of the URL doesn't affect the default filename.
Update 2: I've tried both
content-disposition inline; filename=foo.pdf
Content-Type application/pdf; filename=foo.pdf
and
content-disposition inline; filename=foo.pdf
Content-Type application/pdf; name=foo.pdf
(as verified through Firebug) Sadly, neither worked.
A sample url is
/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true
which translates to a default Acrobat save as filename of
http___localhost_bar_sessions_958d8a22-0_views_1493881172_export_format=application_pdf&no-attachment=true.pdf
Update 3: Julian Reschke brings actual insight and rigor to this case. Please upvote his answer.
This seems to be broken in FF (https://bugzilla.mozilla.org/show_bug.cgi?id=433613) and IE but work in Opera, Safari, and Chrome. http://greenbytes.de/tech/tc2231/#inlwithasciifilenamepdf
Part of the problem is that the relevant RFC 2183 doesn't really state what to do with a disposition type of "inline" and a filename.
Also, as far as I can tell, the only UA that actually uses the filename for type=inline is Firefox (see test case).
Finally, it's not obvious that the plugin API actually makes that information available (maybe someboy familiar with the API can elaborate).
That being said, I have sent a pointer to this question to an Adobe person; maybe the right people will have a look.
Related: see attempt to clarify Content-Disposition in HTTP in draft-reschke-rfc2183-in-http -- this is early work in progress, feedback appreciated.
Update: I have added a test case, which seems to indicate that the Acrobat reader plugin doesn't use the response headers (in Firefox), although the plugin API provides access to them.
Set the file name in ContentType as well. This should solve the problem.
context.Response.ContentType = "application/pdf; name=" + fileName;
// the usual stuff
context.Response.AddHeader("content-disposition", "inline; filename=" + fileName);
After you set content-disposition header, also add content-length header, then use binarywrite to stream the PDF.
context.Response.AddHeader("Content-Length", fileBytes.Length.ToString());
context.Response.BinaryWrite(fileBytes);
Like you, I tried and tried to get this to work. Finally I gave up on this idea, and just opted for a workaround.
I'm using ASP.NET MVC Framework, so I modified my routes for that controller/action to make sure that the served up PDF file is the last part of the location portion of the URI (before the query string), and pass everything else in the query string.
Eg:
Old URI:
http://server/app/report/showpdf?param1=foo¶m2=bar&filename=myreport.pdf
New URI:
http://server/app/report/showpdf/myreport.pdf?param1=foo¶m2=bar
The resulting header looks exactly like what you've described (content-type is application/pdf, disposition is inline, filename is uselessly part of the header). Acrobat shows it in the browser window (no save as dialog) and the filename that is auto-populated if a user clicks the Acrobat Save button is the report filename.
A few considerations:
In order for the filenames to look decent, they shouldn't have any escaped characters (ie, no spaces, etc)... which is a bit limiting. My filenames are auto-generated in this case, and before had spaces in them, which were showing up as '%20's in the resulting save dialog filename. I just replaced the spaces with underscores, and that worked out.
This is by no names the best solution, but it does work. It also means that you have to have the filename available to make it part of the original URI, which might mess with your program's workflow. If it's currently being generated or retrieved from a database during the server-side call that generates the PDF, you might need to move the code that generates the filename to javascript as part of a form submission or if it comes from a database make it a quick ajax call to get the filename when building the URL that results in the inlined PDF.
If you're taking the filename from a user input on a form, then that should be validated not to contain escaped characters, which will annoy users.
Hope that helps.
Try placing the file name at the end of the URL, before any other parameters. This worked for me.
http://www.setasign.de/support/tips-and-tricks/filename-in-browser-plugin/
In ASP.NET 2.0 change the URL from
http://www. server.com/DocServe.aspx?DocId=XXXXXXX
to
http://www. server.com/DocServe.aspx/MySaveAsFileName?DocId=XXXXXXX
This works for Acrobat 8 and the default SaveAs filename is now MySaveAsFileName.pdf.
However, you have to restrict the allowed characters in MySaveAsFileName (no periods, etc.).
Apache's mod_rewrite can solve this.
I have a web service with an endpoint at /foo/getDoc.service. Of course Acrobat will save files as getDoc.pdf. I added the following lines in apache.conf:
LoadModule RewriteModule modules/mod_rewrite.so
RewriteEngine on
RewriteRule ^/foo/getDoc/(.*)$ /foo/getDoc.service [P,NE]
Now when I request /foo/getDoc/filename.pdf?bar&qux, it gets internally rewritten to /foo/getDoc.service?bar&qux, so I'm hitting the correct endpoint of the web service, but Acrobat thinks it will save my file as filename.pdf.
If you use asp.net, you can control pdf filename through page (url) file name.
As other users wrote, Acrobat is a bit s... when it choose the pdf file name when you press "save" button: it takes the page name, removes the extension and add ".pdf".
So /foo/bar/GetMyPdf.aspx gives GetMyPdf.pdf.
The only solution I found is to manage "dynamic" page names through an asp.net handler:
create a class that implements IHttpHandler
map an handler in web.config bounded to the class
Mapping1: all pages have a common radix (MyDocument_):
<httpHandlers>
<add verb="*" path="MyDocument_*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>
Mapping2: completely free file name (need a folder in path):
<add verb="*" path="/CustomName/*.ashx" type="ITextMiscWeb.MyDocumentHandler"/>
Some tips here (the pdf is dynamically created using iTextSharp):
http://fhtino.blogspot.com/2006/11/how-to-show-or-download-pdf-file-from.html
Instead of attachment you can try inline:
Response.AddHeader("content-disposition", "inline;filename=MyFile.pdf");
I used inline in a previous web application that generated Crystal Reports output into PDF and sent that in browser to the user.
File download dialog (PDF) with save and open option
Points To Remember:
Return Stream with correct array size from service
Read the byte arrary from stream with correct byte length on the basis of stream length.
set correct contenttype
Here is the code for read stream and open the File download dialog for PDF file
private void DownloadSharePointDocument()
{
Uri uriAddress = new Uri("http://hyddlf5187:900/SharePointDownloadService/FulfillmentDownload.svc/GetDocumentByID/1/drmfree/");
HttpWebRequest req = WebRequest.Create(uriAddress) as HttpWebRequest;
// Get response
using (HttpWebResponse httpWebResponse = req.GetResponse() as HttpWebResponse)
{
Stream stream = httpWebResponse.GetResponseStream();
int byteCount = Convert.ToInt32(httpWebResponse.ContentLength);
byte[] Buffer1 = new byte[byteCount];
using (BinaryReader reader = new BinaryReader(stream))
{
Buffer1 = reader.ReadBytes(byteCount);
}
Response.Clear();
Response.ClearHeaders();
// set the content type to PDF
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=Filename.pdf");
Response.Buffer = true;
Response.BinaryWrite(Buffer1);
Response.Flush();
// Response.End();
}
}
I believe this has already been mentioned in one flavor or another but I'll try and state it in my own words.
Rather than this:
/bar/sessions/958d8a22-0/views/1493881172/export?format=application/pdf&no-attachment=true
I use this:
/bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf?GeneratePDF=1
Rather than having "export" process the request, when a request comes in, I look in the URL for GeneratePDF=1. If found, I run whatever code was running in "export" rather than allowing my system to attempt to search and serve a PDF in the location /bar/sessions/958d8a22-0/views/1493881172/NameThatIWantPDFToBe.pdf. If GeneratePDF is not found in the URL, I simply transmit the file requested. (note that I can't simply redirect to the file requested - or else I'd end up in an endless loop)
You could always have two links. One that opens the document inside the browser, and another to download it (using an incorrect content type). This is what Gmail does.
For anyone still looking at this, I used the solution found here and it worked wonderfully. Thanks Fabrizio!
The way I solved this (with PHP) is as follows:
Suppose your URL is SomeScript.php?id=ID&data=DATA and the file you want to use is TEST.pdf.
Change the URL to SomeScript.php/id/ID/data/DATA/EXT/TEST.pdf.
It's important that the last parameter is the file name you want Adobe to use (the 'EXT' can be about anything). Make sure there are no special chars in the above string, BTW.
Now, at the top of SomeScript.php, add:
$_REQUEST = MakeFriendlyURI( $_SERVER['PHP\_SELF'], $_SERVER['SCRIPT_FILENAME']);
Then add this function to SomeScript.php (or your function library):
function MakeFriendlyURI($URI, $ScriptName) {
/* Need to remove everything up to the script name */
$MyName = '/^.*'.preg_quote(basename($ScriptName)."/", '/').'/';
$Str = preg_replace($MyName,'',$URI);
$RequestArray = array();
/* Breaks down like this
0 1 2 3 4 5
PARAM1/VAL1/PARAM2/VAL2/PARAM3/VAL3
*/
$tmp = explode('/',$Str);
/* Ok so build an associative array with Key->value
This way it can be returned back to $_REQUEST or $_GET
*/
for ($i=0;$i < count($tmp); $i = $i+2){
$RequestArray[$tmp[$i]] = $tmp[$i+1];
}
return $RequestArray;
}//EO MakeFriendlyURI
Now $_REQUEST (or $_GET if you prefer) is accessed like normal $_REQUEST['id'], $_REQUEST['data'], etc.
And Adobe will use your desired file name as the default save as or email info when you send it inline.
I was redirected here because i have the same problem. I also tried Troy Howard's workaround but it is doesn't seem to work.
The approach I did on this one is to NO LONGER use response object to write the file on the fly. Since the PDF is already existing on the server, what i did was to redirect my page pointing to that PDF file. Works great.
http://forums.asp.net/t/143631.aspx
I hope my vague explanation gave you an idea.
Credits to Vivek.
Nginx
location /file.pdf
{
# more_set_headers "Content-Type: application/pdf; name=save_as_file.pdf";
add_header Content-Disposition "inline; filename=save_as_file.pdf";
alias /var/www/file.pdf;
}
Check with
curl -I https://example.com/file.pdf
Firefox 62.0b5 (64-bit): OK.
Chrome 67.0.3396.99 (64-Bit): OK.
IE 11: No comment.
Try this, if your executable is "get.cgi"
http://server,org/get.cgi/filename.pdf?file=filename.pdf
Yes, it's completely insane. There is no file called "filename.pdf" on the server, there is directory at all under the executable get.cgi.
But it seems to work. The server ignores the filename.pdf and the pdf reader ignores the "get.cgi"
Dan