ReadAllBytesAsync(path) path always combined with the contentrootpath - c#

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.

Related

Xamarin media plugin get android image path

I am using the media plugin for xamarin forms (by james montemagno) and the actual taking of the picture and storing it works fine, I have debugged the creation of the image on the emulator and it is stored in
/storage/emulated/0/Android/data/{APPNAME}.Android/files/Pictures/{DIRECTORYNAME}/{IMAGENAME}
however in my app it will get a list of file names from an API I want to check if the image exists in that folder.
The following works fine on IOS
var documentsDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, App.IMAGE_FOLDER_NAME);
jpgFilename = System.IO.Path.Combine(jpgFilename, name);
I have tried the 2 following methods for getting it on android but both are incorrect
var documentsDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string jpgFilename = System.IO.Path.Combine(documentsDirectory, App.IMAGE_FOLDER_NAME);
jpgFilename = System.IO.Path.Combine(jpgFilename, name);
Java.IO.File dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DataDirectory + "/" + App.IMAGE_FOLDER_NAME + "/" + name);
dir ends up as
/storage/emulated/0/data/{DIRECTORY}/{IMAGENAME}
jpgFileName ends up as /data/data/{APPNAME}.Android/files/{DIRECTORYNAME}/{IMAGENAME}
I dont want to hardcode anything in the paths but neither of these are right. I could not find anything in the GIT documentation for getting the file path except by looking at the path of the file created when taking a picture
The problem
I had the same kind of issue with Xamarin Media Plugin. For me, the problem is:
we don't really know where the plugin save the picture on android.
After reading all documentation I found, I just noted this:
... When your user takes a photo it will still store temporary data, but also if needed make a copy to the public gallery (based on platform). In the MediaFile you will now see a AlbumPath that you can query as well.
(from: Github plugin page)
so you can save your photo to your phone gallery (it will be public) but the path is known.
and we don't know what means "store the temporary data".
Solution
After investigating on how/where an app can store data, I found where the plugin stores photos on Android >> so I can generate back the full file names
In your Android app, the base path you are looking for is:
var basePath = Android.App.Application.Context.GetExternalFilesDir(null).AbsolutePath
It references your app's external private folder. It looks like that:
/storage/emulated/0/Android/data/com.mycompany.myapp/files
So finally to get your full file's path:
var fullPath = basePath + {DIRECTORYNAME} + {FILENAME};
I suggest you to make a dependency service, for instance 'ILocalFileService', that will expose this 'base path' property.
Please let me know if it works for you !
I resolved a similar problem. I wanted to collect all files for my app in a folder visible to all users.
var documentsDirectory = Android.OS.Environment.GetExternalStoragePublicDirectory(
Android.OS.Environment.DirectoryDocuments);
If you want to create Directory, add to your class using System.IO; and you have the same functions in a normal .NET application.
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
If you want to create files or directory, you can use PCLStorage.
public async Task<bool> CreateFileAsync(string name, string context)
{
// get hold of the file system
IFolder folder = FileSystem.Current.LocalStorage;
// create a file, overwriting any existing file
IFile file = await folder.CreateFileAsync(name,
CreationCollisionOption.ReplaceExisting);
// populate the file with some text
await file.WriteAllTextAsync(context);
return true;
}
to get the private path
var privatePath = file.Path;
to get the public Album path
var publicAlbumPath = file.AlbumPath;
se the documentation here https://github.com/jamesmontemagno/MediaPlugin

Saving an uploaded file with HttpPostedFileBase.SaveAs in a physical path

I'd like to save an uploaded file to a physical path by the method HttpPostedFileBase.SaveAs().
When I choose a physical path, an exception appears indicates that the path must be virtual.
var fileName = Path.GetFileName(fileurl.FileName);
var path = "C:/Projets" + fileName;
fileurl.SaveAs(Server.MapPath(path));
How can I change my code to be able to save the file every where I want?
The Server.MapPath works only with physical locations that are part of the website. If you want to save the file outside you could use the following:
var fileName = Path.GetFileName(fileurl.FileName);
fileurl.SaveAs(Path.Combine(#"c:\projects", fileName));
Make sure though that the account under which your application pool is executing is granted write permissions to this folder.
Server.MapPath is for virtual path. You can try to use Path.GetFullPath(path).

Server.MapPath Could not find a part of the path in ASP.net MVC

I have the slide show that get the images in my local folder to display in my Site.Master page.
So I used :
FileInfo[] files = new DirectoryInfo(Server.MapPath("~" + "/path/blahblah/")).GetFiles();
It works fine for me when I run the project in the local, but now I changed my project throw the port http://195.155.10.521:8081, then it had one error Could not find a part of the path 'D:\path\blahblah\'.
Thanks for any help anyone can give me!
The port number on which the site is hosted doesn't really matter for the Server.MapPath method. So try splitting the method calls in order to more easily identify the problem:
var path = Server.MapPath("~/path/blahblah/");
var di = new DirectoryInfo(path);
var files = di.GetFiles();
If the error message you are getting is Could not find a part of the path 'D:\path\blahblah\' then this probably means that the D:\path\blahblah\ folder doesn't exist on your server.
var path = Server.MapPath("~/Reproting/Cashstatement.pdf");
byte[] FileBytes = System.IO.File.ReadAllBytes(path);
return File(FileBytes, "application/pdf");

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.

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

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");

Categories