MapPath vs VirtualPathUtility.ToAbsolute - c#

I am using c#, asp.net and working on a web application.
I initially had a relative path as such which I needed to be an absolute path.
The below works but need to get the absolute path:
return Chart.RenderChartHTML("../../Charts/MSLine.swf");
I tried the following which didn't work (note that it gives me the complete path on my hard drive to .swf):
string mslinepath = HttpContext.Current.Server.MapPath("Charts/MSLine.swf");
return Chart.RenderChartHTML(mslinepath);
I then tried the following which works:
string mslinepath = VirtualPathUtility.ToAbsolute("~/Charts/MSLine.swf");
return Chart.RenderChartHTML(mslinepath);
Wondering why VirtualPathUtility.ToAbsolute works while the other one doesn't.

MapPath returns the physical file path on your server which corresponds to the specified virtual path.
(Eg: "C:\inetpub\wwwroot\Charts\MSLine.swf")
ToAbsolute converts an app-relative virtual path (one starting with "~/") to an absolute virtual path.
(Eg: "/AppName/Charts/MSLine.swf")

Related

Read text file from relative path within project

I am creating a unit test which works using the following exact path:
string path = #"/Users/{username}/Coding/computershare/ChallengeSampleDataSet1.txt";
I read the text from the file by passing this path
string pricesFromFile = System.IO.File.ReadAllText(path);
However, I do not want to hardcode the complete local file path - I want to use the relative path in the project directory.
Therefore I tried the below using other articles on StackOverflow:
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "ChallengeSampleDataSet1.txt");
But file is not found. How can I fix this so that I'm able to load the file when running the app from another machine?
Edit: the error in console using the second method is
System.IO.FileNotFoundException : Could not find file '/Users/{username}/Coding/computershare/bin/Debug/net5.0/ChallengeSampleDataSet1.txt'.
This should do the trick:
string path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory + #"..\..\..\", "ChallengeSampleDataSet1.txt");
Note the direction of the slash (\)
Since the error is "/Users/{username}/Coding/computershare/bin/Debug/net5.0/ChallengeSampleDataSet1.txt" it indicates that your base directory is /bin/debug/net5.0 down from the root of the code. By double dotting up three levels, you'll be able to find the file in question.

Dealing with paths in MVC libraries

I have an MVC project and a class library just for saving and deleting images.
I have the path to those images stored in a variable as a relative path
Content\images\ that I reference inside the Save() and Delete() methods.
The save method works as I would think but the delete throws an error as it's relating the current path from the window directory.
// Works fine
File.WriteAllBytes(Path.Combine(Settings.ImagesPath, filename), binaryData);
// Error saying it cannot find the path in the C:\windows\system32\folder
File.Delete(Path.Combine(Settings.ImagesPath, filename));
I'd like to be able to switch between relative and absolute paths in my Settings.ImagesPath string but every SO article I've tried works for one scenario or the other. What's the best way to convert absolute or relative paths to some common way to deal with them?
You should use Server.MapPath method to generate the path to the location and use that in your Path.Combine method.
var fullPath = Path.Combine(Server.MapPath(Settings.ImagesPath), filename);
System.IO.File.Delete(fullPath);
Server.MapPath method returns the physical file path that corresponds to the specified virtual path. In this case, Server.MapPath(Settings.ImagesPath) will return the physical file path to your Content\images\ which is inside your app root.
You should do the same when you save the file as well.
You can also check the existence of the file before attempting to delete it
var fullPath = Path.Combine(Server.MapPath(Settings.ImagesPath), filename);
if (System.IO.File.Exists(fullPath))
{
System.IO.File.Delete(fullPath);
}
Server.MapPath expects a relative path. So if you have an absolute value in the Settings.ImagePath, You can use the Path.IsPathRooted method to determine if it is a virtual path or not
var p = Path.Combine(Path.IsPathRooted(Settings.ImagesPath)
? path : Server.MapPath(Settings.ImagesPath), name);
if (System.IO.File.Exists(p))
{
System.IO.File.Delete(p);
}
When you use the virutal path, make sure it start with ~.
Settings.ImagesPath = #"~\Contents\Pictures";

Server.MapPath issue?

So I am reading a book about asp.net security. and one of the sections there was :
how to prevent directory traversal filename ( hacked filenames).
so the line of code was :
string fullPath = Server.MapPath(System.IO.Path.Combine(#"d:\inetpub\inbound\",filename));
but then I noticed the result of the combine which will be :
d:\inetpub\inbound\myfile.txt
But I remember that the parameter type should be virtual path and not filesystem path !
d:\inetpub\inbound\myfile.txt is not a virtual path!
what am I missing ?
p.s. this is the book : (wrox)
The code sample is wrong.
The role of Server.MapPath is indeed to transform a virtual path into a physical one. If you already have a physical path, there'a no need for Server.MapPath.
The code will probably throw an Exception with the message:
'd:\inetpub\inbound\myfile.txt' is a physical path, but a virtual path was expected.
You must use Server.MapPath to convert a virtual path (i.e., a path inside your website) to a physical path (such as D:\InetPub\...).
So you can do this:
var physicalPath = Server.MapPath("~/Incoming/Receivedfile.txt");
and then you can use physicalPath to actually access the file.
BTW the tilde in the filename above represents the root of the website the code is running under.

Converting physical path to relative one in respect of http://localhost:

I use asp.net 4 and c#.
I have this code that allow me to find the physical path for an image.
As you can see I get my machine physical pagh file:///C:.
string pathRaw = HttpContext.Current.Request.PhysicalApplicationPath + "Statics\\Cms\\Front-End\\Images\\Raw\\";
Result:
file:///C:/......../f005aba1-e286-4d9e-b9db-e6239f636e63.jpg
But I need display this image at the Front end of my web application so I would need a result like this:
http://localhost:1108/Statics/Cms/Front-End/Images/Raw/f005aba1-e286-4d9e-b9db-e6239f636e63.jpg
How to do it?
PS: I need to convert the result of variable pathRaw.
Hope I was able to express myself unfortunately I'm not sure about terminology in this case.
Thanks for your help!
The easiest thing to do is get rid of the physical application path.
If you cannot do that in your code, just strip it off the pathRaw variable. Like this:
public string GetVirtualPath( string physicalPath )
{
if ( !physicalPath.StartsWith( HttpContext.Current.Request.PhysicalApplicationPath ) )
{
throw new InvalidOperationException( "Physical path is not within the application root" );
}
return "~/" + physicalPath.Substring( HttpContext.Current.Request.PhysicalApplicationPath.Length )
.Replace( "\\", "/" );
}
The code first checks to see if the path is within the application root. If not, there's no way to figure out a url for the file so an exception is thrown.
The virtual path is constructed by stripping off the physical application path, convert all back-slashes to slashes and prefixing the path with "~/" to indicate it should be interpreted as relative to the application root.
After that you can convert the virtual path to a relative path for output to a browser using ResolveClientUrl(virtualPath).
Get the root of your application using Request.ApplicationPath
then use the answer from this question to get a relative path.
It might need a bit of tweaking but it should allow you to do what you're after.
Left-strip your pathRaw content by the Request.ApplicationPath and construct the url using
Uri navigateUri = new Uri(System.Web.HttpContext.Current.Request.Url, relativeDocumentPath);
Make use of
ApplicationPath - Gets the ASP.NET application's virtual application root path on the server.
Label1.Text = Request.ApplicationPath;
Image1.ImageUrl = Request.ApplicationPath + "/images/Image1.gif";
You can use Server.MapPath for this.
string pathRaw = System.Web.HttpContext.Current.Server.MapPath(“somefile.jpg“);

Server.MapPath - Physical path given, virtual path expected

I'm using this line of code:
var files = Directory.GetFiles(Server.MapPath("E:\\ftproot\\sales"));
to locate files in a folder however I get the error message saying that
"Physical Path given but virtual path
expected".
Am new enough to using System.IO in C# so I was wondering if it's possible to enter a physical path to do this?
if you already know your folder is: E:\ftproot\sales then you do not need to use Server.MapPath, this last one is needed if you only have a relative virtual path like ~/folder/folder1 and you want to know the real path in the disk...
var files = Directory.GetFiles(#"E:\ftproot\sales");

Categories