WebClient.DownloadFile only see's Local????

G

Guest

Why does WebClient.DownloadFile loose my completed path?

Ok, I have a function in my app then when my button is clicked it checks to
see if the files come from a local drive or a http address. The portion of
the code that pulls from the drive works great, but when the http address is
active it changes the originating path to my C:\Windows\System32 folder
instead of the proper path.

I keep the path as a field on my form so I am certain it is correct.

This is my onclick function!

string fileName = BoxImageName.Text;
string filePath = BoxImagePath.Text;

if(Configuration.imageDirType == "Drive")
{
FileInfo MyFileInfo;
long StartPos = 0, FileSize;
MyFileInfo = new FileInfo(filePath);
FileSize = MyFileInfo.Length;

Response.ContentType = "application/x-msdownload";
Response.AppendHeader( "content-disposition","attachment; filename=" +
fileName);
Response.WriteFile(filePath, StartPos, FileSize);
Response.End();
}
else if(Configuration.imageDirType == "WWW")
{
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile(filePath,fileName);
}

The BoxImagePath.Text does have the right information in it, when you copy
it's contents to a browser window it displays perfectly, so the path is
correct.

What else could I be missing??
Is there a better way I should be doing this??
Is there a way to force this download to prompt for a saveas location like
the x-msdownload does??

Thanks all!
 
S

Steven Cheng[MSFT]

Hi Dewright,

Welcome to ASP.NET newsgroup.
From your description and the code snippet, you're performing a file
downloading task and the source file may come from local disk or on a
remote server and exposed through http url address. Also ,when the file is
on remote address, you'll use Webclient.DownloadFile to retrieve it to
local disk. However, you found that when calling the WebClient.DownLoad
file, it'll always save the file under the "C:\Windows\System32" folder
rather than your current app's folder, yes?

Based on my understanding, the problem you met is likely caused by the
Default "Current Directory" value of the ASP.NET worker process. Is the
"fileName" you specified in

myWebClient.DownloadFile(filePath,fileName);

a relative path (or just a file name without full path), if so the runtime
will assume that it's in the current directory and concate it with the
current directory value. And for windows process, sub process will inherit
the current directory value from it's parent process(creator process). And
ASP.NET's worker process is created at the first time a certain asp.net
page being requested by the IIS's service process, so it'll inherit the IIS
process's current dir value which is

"c:\windows\system32\inetsrv"

You can call "System.IO.Directory.GetCurrentDirectory()" to verify this.
Also, if you want to change the current dir value, we can use the

System.IO.Directory.SetCurrentDirectory(Server.MapPath("~/"));

to assign the application's root dir as the current dir. So I think you
can try adjusting the current dir value before calling webclient.DownLoad
file to see whether it helps.

Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi Dewright,

Thanks for your followup.
As you mentioned that you using the following statement to call
WebClient.DownLoadFile:

myWebClient.DownloadFile("http://tgrams/imageviewer/mt/notes/20/ne/12/mt2030
0202.tif","mt20300202.tif")

That means you'll request the file at

http://tgrams/imageviewer/mt/notes/20/ne/12/mt20300202.tif

and save it on your local machine as "mt20300202.tif". In fact, the
WebClient.DownLoadFile will perform the following steps internally:

1. Use HttpWebRequest to request the file through the url you
specified(http://tgrams/imageviewer/mt/notes/20/ne/12/mt20300202.tif)

2. Then, read the responseStream from the above httpWebRequest and create a
FileStream through the local path you specified (the second param in the
DownLoadFile method). Also, since you specify a relative path, runtime will
append it with the current directory's path( for ASP.NET, it is
"c:\windows\system32\inetsrv"). So if the DownloadFile function correctly,
we can find that the file is downloaded and saved at

"c:\windows\system32\inetsrv\mt20300202.tif", is this what you got
currently? If so, this is the correct and expected behavior. If not ,
would you try using "WebClient.DownLoadData" to see whether it can
correctly retrieve the file stream from the remote url. If DownloadData
function correctly, I still think the problem is with your local file path.

Please feel free to post here if there're anything unclear. Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Hi Steven;

Ok, I did go through and try your suggestion, I used this to get a buffer of
the file,

WebClient fileClient = new WebClient();
fileClient.Headers.Add("Content-Type: application/x-msdownload");
byte [] myDataBuffer = fileClient.DownloadData(filePath);
string download = Encoding.ASCII.GetString(myDataBuffer);
Response.Write(download);

When I run this I get a stream of text to my screen that does show the file
contents, based on the Multi-Page TIF V2 header in the text.

Alas if I turn the Response.Write to a WriteFile it gives the same exception
as below.

This doesn't make much sense to me, as I am able to get the stream to
display but if I try to write it to a file it chokes again.

Thoughts?
 
S

Steven Cheng[MSFT]

Hi Dewright,

Thanks for your response. So I think the code worked well in your web app,
I think there maybe some misunderstanding on the WebClient.DownLoadFile
method. This method will only retrieve the filestream from the remote url
then save it to a
"LOCAL FILE" on the machine (where your code executing). So if you want to
write it down to your asp.net app's client, we must use Response.WriteFile
and provide the filepath where the "DownLoadFile" saved that remote stream
to write it to our web application's client user. So the typical code will
be something like:

=======================
string url = "http://remoteserver/folder/file.ext";
WebClient wc = null;

string path = "~/temp/";
string filename = DateTime.Now.Ticks + ".tmp";

try
{
wc = new WebClient();

wc.DownloadFile(url, Server.MapPath(path + filename));

Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("ContentType","application/octet-stream");
Response.AddHeader("Content-Disposition", "attachment;
filename=aspnet.html");

Response.WriteFile(Server.MapPath(path+filename));

Response.End();

}
catch(System.Threading.ThreadAbortException taex)
{
//do nothing just to bypass the ThreadAbortException
}
catch(WebException webex)
{
Response.Write("<br>" + webex.ToString());
}
catch(Exception ex)
{
Response.Write("<br>" + ex.ToString());
}
=========================

In the above code snippet, I first use WebClient.DownLoadFile to save the
file in my server's "temp" folder which is under my applciation's root dir.
Then use Response.WriteFile to write it out.

So we can see that using Webclient.Download file is not a good approach in
such scenario, we can directly use DownLoadData to retrieve the binary
stream and then write it into Respons.OutputStream directly which won't
need the additional temp file on our server machine. How do you think ?

If there're anything unclear, please feel free to let me know. Thanks,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Ok, I see what you are going.

Is it possible to do a WebClient.DownloadFile to the user if the file is
coming from my own virtual directory? I mapped the folder to my approot as a
scannedimages folder that I can now access from my site.

Thoughts?
 
G

Guest

This is great, I adapted what you posted to my files and it is working great.
So I am now just putting into place a function to delete the tmp file after
the response.end.

Thanks for your help with the logic!
 
S

Steven Cheng[MSFT]

You're welcome Dewright,

Also, I think you can also consider using the WebClient.DownloadData which
return the byte[] stream of the remote data, thus we can directly write
that byte stream into our response's output buffer (no temp file needed).
Anyway, you can choose the one you feel most convenient.

Thanks again for your posting.

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top