Absolute path back to web-relative path

2019-01-04 23:37发布

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?

6条回答
霸刀☆藐视天下
2楼-- · 2019-01-05 00:09

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.

查看更多
来,给爷笑一个
3楼-- · 2019-01-05 00:22

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.");
}
查看更多
【Aperson】
4楼-- · 2019-01-05 00:25

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);
查看更多
The star\"
5楼-- · 2019-01-05 00:26

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.

查看更多
6楼-- · 2019-01-05 00:28

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(@"\", "/");
}
查看更多
孤傲高冷的网名
7楼-- · 2019-01-05 00:30

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);
查看更多
登录 后发表回答