Absolute path back to web-relative path

C#asp.net.NetPathMappath

C# Problem Overview


If I have managed to locate and verify the existence of a file using Server.MapPath and I now want to send the user directly to that file, what is the fastest way to convert that absolute path back into a relative web path?

C# Solutions


Solution 1 - C#

Perhaps this might work:

String RelativePath = AbsolutePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);

I'm using c# but could be adapted to vb.

Solution 2 - C#

Wouldn't it be nice to have Server.RelativePath(path)?

well, you just need to extend it ;-)

public static class ExtensionMethods
{
    public static string RelativePath(this HttpServerUtility srv, string path, HttpRequest context)
    {
        return path.Replace(context.ServerVariables["APPL_PHYSICAL_PATH"], "~/").Replace(@"\", "/");
    }
}

With this you can simply call

Server.RelativePath(path, Request);

Solution 3 - C#

I know this is old but I needed to account for virtual directories (per @Costo's comment). This seems to help:

static string RelativeFromAbsolutePath(string path)
{
    if(HttpContext.Current != null)
    {
        var request = HttpContext.Current.Request;
        var applicationPath = request.PhysicalApplicationPath;
        var virtualDir = request.ApplicationPath;
        virtualDir = virtualDir == "/" ? virtualDir : (virtualDir + "/");
        return path.Replace(applicationPath, virtualDir).Replace(@"\", "/");
    }

    throw new InvalidOperationException("We can only map an absolute back to a relative path if an HttpContext is available.");
}

Solution 4 - C#

I like the idea from Canoas. Unfortunately I had not "HttpContext.Current.Request" available (BundleConfig.cs).

I changed the methode like this:

public static string RelativePath(this HttpServerUtility srv, string path)
{
     return path.Replace(HttpContext.Current.Server.MapPath("~/"), "~/").Replace(@"\", "/");
}

Solution 5 - C#

If you used Server.MapPath, then you should already have the relative web path. According to the MSDN documentation, this method takes one variable, path, which is the virtual path of the Web server. So if you were able to call the method, you should already have the relative web path immediately accessible.

Solution 6 - C#

For asp.net core i wrote helper class to get pathes in both directions.

public class FilePathHelper
{
    private readonly IHostingEnvironment _env;
    public FilePathHelper(IHostingEnvironment env)
    {
        _env = env;
    }
    public string GetVirtualPath(string physicalPath)
    {
        if (physicalPath == null) throw new ArgumentException("physicalPath is null");
        if (!File.Exists(physicalPath)) throw new FileNotFoundException(physicalPath + " doesn't exists");
        var lastWord = _env.WebRootPath.Split("\\").Last();
        int relativePathIndex = physicalPath.IndexOf(lastWord) + lastWord.Length;
        var relativePath = physicalPath.Substring(relativePathIndex);
        return $"/{ relativePath.TrimStart('\\').Replace('\\', '/')}";
    }
    public string GetPhysicalPath(string relativepath)
    {
        if (relativepath == null) throw new ArgumentException("relativepath is null");
        var fileInfo = _env.WebRootFileProvider.GetFileInfo(relativepath);
        if (fileInfo.Exists) return fileInfo.PhysicalPath;
        else throw new FileNotFoundException("file doesn't exists");
    }

from Controller or service inject FilePathHelper and use:

var physicalPath = _fp.GetPhysicalPath("/img/banners/abro.png");

and versa

var virtualPath = _fp.GetVirtualPath(physicalPath);


 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiontags2kView Question on Stackoverflow
Solution 1 - C#GateKillerView Answer on Stackoverflow
Solution 2 - C#CanoasView Answer on Stackoverflow
Solution 3 - C#AlexCuseView Answer on Stackoverflow
Solution 4 - C#Pierre ChavarocheView Answer on Stackoverflow
Solution 5 - C#Yaakov EllisView Answer on Stackoverflow
Solution 6 - C#Lapenkov VladimirView Answer on Stackoverflow