14
votes

As we know that a virtual direcoty can be linked to a folder with a diffrent name, how can I get the physical path of a virtual directory ?

I've been trying with HttpContext.Current.server.MapPath but it returns me the physic path plus the path I send in parameter even if the directory doesn't even exist or if it exists with a diffrent name.

Exemple :

C:\blabla\Sites\Application1\Imaageesss - On disc

Application1\Images (In ISS, my virutal directory)

But if I do a MapPath on "/Images" it will never give me C:\blabla\Sites\Application1\Imaageesss but C:\inetpub\wwwroot\Images which is not the real directory linked to.

6
All the answer below do not solve the problem. I assume MapPath is not smart enough to check if it's a virtual IIS directory or not. It just adds the application root path to the path you provide. Unfortunately I couldn't find a solution for this even after intensively searching the web. - needfulthing
Found a way, see answer below. - needfulthing
I had a similar problem under two different circumstances. I had to call Server.MapPath("/Application1/Images/image.jpg") instead of Server.MapPath("/Images/image.jpg") in one situation, and the other it just turned out I mis-referenced my virtual directory name within my application. I had the same result the OP was experiencing until I did each of these things. Just thought I'd add on... - ionalchemist

6 Answers

15
votes
Server.MapPath("~/Images")

is the correct way to go about it as "~" references the root of your application.

8
votes

This is what worked for me:

string physicalPath =    
System.Web.Hosting.HostingEnvironment.MapPath(HttpContext.Current.Request.ApplicationPath);
3
votes

What if you try this little snippet?

string physicalPath = HttpContext.Current.Request.MapPath(appPath);
1
votes

After some more research I was able to create a method to get the physical path of a virtual IIS directory:

public static string VirtualToPhysicalPath(string vPath) {
    // Remove query string:
    vPath = Regex.Replace(vPath, @"\?.+", "").ToLower();

    // Check if file is in standard folder:
    var pPath = System.Web.Hosting.HostingEnvironment.MapPath("~" + vPath);
    if (System.IO.File.Exists(pPath)) return pPath;

    // Else check for IIS virtual directory:
    var siteName = System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
    var sm = new Microsoft.Web.Administration.ServerManager();
    var vDirs = sm.Sites[siteName].Applications[0].VirtualDirectories;
    foreach (var vd in vDirs) {
        if (vd.Path != "/" && vPath.Contains(vd.Path.ToLower())) pPath = vPath.Replace(vd.Path.ToLower(), vd.PhysicalPath).Replace("/", "\\");
    }
    return pPath;
}

Caveat: this solution assumes that you only have a root application (Applications[0]).

1
votes

The following should work just fine:

var physicalPath = HostingEnvironment.MapPath("~/MyVirtualDirectory");
0
votes

This might answer your question:

http://msdn.microsoft.com/en-us/library/system.web.httprequest.physicalpath.aspx

However, I can't currently provide an example, because I have got a lot of work to do. When I'll find some time I'll send detailed information.