Problem with relative path in System.file.io of asp.net - c#

I'm storing the file path in the database as ~/FolderName/FileName and when i try to open the file using System.IO.FileInfo(filePath) in this manner. It is not able to decipher the file path. Moreover i'm using this statement in a class DownloadFile, so i'm not able to use Page.Server.MapPath. Is there a work around for this problem.
These are the following lines of code that i'm using:
if (dr1.Read())
{
String filePath = dr1[0].ToString();
HttpContext.Current.Response.ContentType = "APPLICATION/OCTET-STREAM";
String disHeader = "Attachment; Filename=\"" + fileName + "\"";
HttpContext.Current.Response.AppendHeader("Content-Disposition", disHeader);
System.IO.FileInfo fileToDownload = new System.IO.FileInfo(filePath);
string fullName = fileToDownload.FullName;
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.WriteFile(fileToDownload.FullName);
sqlCon.Close();
}
where the filepath is of the format ~/ComponentFolderForDownloading/FileName.exe
How can i solve this problem?

If you can't use Server.MapPath for determining the file location, you need to use something else. The FileInfo class can not take an ASP.NET virtual path in its constructor. It needs the real, physical path of the file.
You'll need to strip the ~/ from the front of the path; perhaps exchange the / for a \, and then use Path.Combine with the root directory of your application to find the physical location. But that assumes that your locations are in physical directories - not virtual ones.
Server.MapPath was, of course, made specifically to do this.
An alternative would be to store the real, physical locations of the files in the DB; either in addition to or in stead of the virtual, ASP.NET ones.

If you know you are running in IIS, you can use:
HttpContext.Current.Server.MapPath("~/someurl");

Related

ReadAllBytesAsync(path) path always combined with the contentrootpath

I want to return a files from virtual path directory, currently this is my code in C# asp net core.
var path = GetConfig.AppSetting["VirtualDirectoryPath:PathLocal"] + "/" +
_.data.Downloadpath;
var provider = new FileExtensionContentTypeProvider();
if (!provider.TryGetContentType(path, out var contentType))
{
contentType = "application/octet-stream";
}
var bytes = await System.IO.File.ReadAllBytesAsync("http://website.com/foldername/foldername/filename.pdf");
return File(bytes, contentType, Path.GetFileName(path));
the DownloadPath contains 'foldername/filename.pdf', and the virtual directory path contains the localhost domain, i tried to hardcode the path but it keeps returning "D://folder/folder/http://website.com/foldername/foldername/filename.pdf". I don't know why the url combined with the contentrootpath, can someone help me?
Actually, i also want to retrieve a virtual directory path as url from the virtual directory that i already created in the iis so that i can download the files from the url. I don't know how to code better, if you can help me with this too i'd very much appreciate it. TIA.
Ultimately, the problem is that you seem to believe File.ReadAllBytesAsync downloads files from the web, it does not. It only reads files on your local file system.
And because http:// files aren't supported, they're not considered to be rooted, and so it gets concatenated to the "current folder" and you get what you see.
Also never concatenate paths like that, that's what Path.Combine is for.

Invalid Characters in Path while Compression in C#

I am having a problem where I am trying to ZIP up a file using the below code :-
Process msinfo = new Process();
msinfo.StartInfo.FileName = "msinfo32.exe";
string path = "\"" + Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + #"\test.nfo" + "\"";
string zippath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + #"\test.nfo";
MessageBox.Show(path);
msinfo.StartInfo.Arguments = #"/nfo "+path;
//msinfo.Start();
//msinfo.WaitForExit();
//MessageBox.Show("The File Has Been Saved!");
ZipFile.CreateFromDirectory(zippath, #"C:\Test.zip");
MessageBox.Show("Everything Is Done!");
The error that is coming is that the Folder path is not valid. I also tried by including quotation marks in the Zippath variable but it did not work.
PS - My machine name has 3 words so it has got spaces as well. Help is appreciated ^_^
The first argument of ZipFile.CreateFromDirectory should be a path of a directory, not a file (test.nfo in this case).
If you want compress the whole directory (e.g. the Desktop dir) then omit the "test.nfo" from the path, like this:
string zippath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
If you want to create a zip archive from only one file then use the ZipFileExtensions.CreateEntryFromFile.
One more thing: when you want to build a path from two or more components use the Path.Combine method instead of simple string concatenation. It can spare you from a lot of pain (like adding path separator characters).

Distributing and there is some problems

I will be distributing my program. It will take pictures and save them to a folder. The problem is: C:/Users/G73/Desktop/
Everyone has there own file path... In the code it is
bitmap.Save("C:/Users/G73/Desktop/My OVMK Photos//OpenVMK" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg", ImageFormat.Jpeg);
It has my File path and the name of my computer... How would I make it to change to the users path?
Try this code:
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
bitmap.Save(Path.Combine(path, "My OVMK Photos//OpenVMK", DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg"), ImageFormat.Jpeg);
It gets Desktop path for current user. You can get more special folders using Enviroment.SpecialFolder
To get the user's desktop -
Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Which you would use with a Path.Combine - e.g.:
bitmap.Save (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "My OVMK Photos//OpenVMK...
Though for images you'd likely be better off using the My Pictures directory -
Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
Try this
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));

Save Paths, Virtual directories, and static locations

I had a file upload that was uploading to a folder in the web application root, i.e. I had
string savePath = #"~/documentation/"
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(Server.MapPath(savePath) + filename);
and that worked fine, uploading the file to WebApp/documentation/filename.abc
The problem is, I want to change the documentation location so I don't have to move that folder when pushing from development to production. So I did the following
In Web.Config:
<appSettings>
<add key="DocumentationLocation" value="C:\Documentation\" />
</appSettings>
In the code:
string savePath = ConfigurationSettings.AppSettings["DocumentationLocation"];
string filename = Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(Server.MapPath(savePath) + filename);
I figured this would work identically, saving the file to the folder specified in the web.config.
However, I get an error when I try to upload a document now, that says:
'C:\TM_Documentation\' is not a valid virtual path.
any idea what i'm doing wrong so that i can fix it and save the files outside of the web app directory? Thanks.
Remove the Server.MapPath(), you don't need the server to map the path for you, because you are giving a full path already.
You don't need a Server.MapPath if you have your path as "C:\Documentation\".
Server.MapPath is required only if you config has a relative path such as "~/Documentation/"
Try this
FileUploadControl.SaveAs(savePath + filename);

Relative, Direct URL

I have a little question about my URL .
I use a tree view on my asp page that's why I use this getcurrentdirectory .
//DirectoryInfo di = new DirectoryInfo("~" + GetTheCurrentDirectory
(selectedNodeValue));
~ = C://Inetpub//WwwRoot//
GetTheCurrentDirectory = Projects//Folder1//
So for the moment it's fine because i Can load all the files for a folder.
After I try to download the files when you click on it .
protected void Page_Load(object sender, EventArgs e)
{
string path = Request["path"].ToString();
string filename = Request["file"].ToString();
fileDownload(filename, Server.MapPath("~\\" + path + filename));
}
So I can retrieve the Path wich is the current directory . The method I use in my other page.
In the server.MapPatch should I put ~ also ? Because when I do that is works localy, but when I put this on my server , the downloading part doesn't work so I suppose this is a URL issue, I can't debug so I am really lost about this !
I changed some things :
DirectoryInfo di = new DirectoryInfo(GetTheCurrentDirectory(selectedNodeValue));
So its returns the same thing .
So now in the server.MapPath the path equal something like Projects//Folder 1//
It works locally, but still not on the server ...
Try this:
fileDownload(filename, Server.MapPath("~/" + path + filename));
And also, as a best practice, don't use + to concatenate strings. You should use string.format, so I would write the above line as follows:
fileDownload(filename, Server.MapPath(string.format("~/{0}{1}", path, filename)));
Just to help you understand your problem better, Server.MapPath will return you a physical file path on the server which corresponds to the virtual path on the web server. i.e. it converts "http://website.com/img.jpg" to something like "C:\mywebsite\img.jpg"
UPDATE:
Make sure the folder you're trying to save the file to, is not read-only and you have permissions to create files in the folder.

Categories