Caminho absoluto para web-caminho relativo
Pergunta
Se eu consegui localizar e verificar a existência de um arquivo usando o Servidor.MapPath e agora quero enviar o usuário diretamente para o arquivo, que é o mais rápido caminho de converter-se que o caminho absoluto para um parente do caminho web?
Solução
Talvez isso pode funcionar:
String RelativePath = AbsolutePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);
Eu estou usando c#, mas pode ser adaptado para vb.
Outras dicas
Não seria bom ter Server.RelativePath(caminho)?
bem, você só precisa estender-lo; -)
public static class ExtensionMethods
{
public static string RelativePath(this HttpServerUtility srv, string path, HttpRequest context)
{
return path.Replace(context.ServerVariables["APPL_PHYSICAL_PATH"], "~/").Replace(@"\", "/");
}
}
Com isso, você pode simplesmente chamar
Server.RelativePath(path, Request);
Eu sei que isso é antigo, mas eu precisava conta para diretórios virtuais (por @Costo comentário).Isso parece ajudar:
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.");
}
Eu gosto da idéia de Canoas.Infelizmente eu não tinha "HttpContext.Atual.Pedido de" disponível (BundleConfig.cs).
Eu mudei methode como este:
public static string RelativePath(this HttpServerUtility srv, string path)
{
return path.Replace(HttpContext.Current.Server.MapPath("~/"), "~/").Replace(@"\", "/");
}
Se tiver utilizado o Servidor.MapPath, em seguida, você já deve ter relativa do caminho web do.De acordo com o Documentação do MSDN, este método leva a uma variável, caminho, qual é o caminho virtual do servidor Web.Então, se você fosse capaz de chamar o método, você já deve ter relativa do caminho web acessível imediatamente.
Para asp.net núcleo escrevi classe auxiliar para obter pathes em ambas as direções.
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");
}
a partir de Controlador ou serviço injetar FilePathHelper e usar:
var physicalPath = _fp.GetPhysicalPath("/img/banners/abro.png");
e versa
var virtualPath = _fp.GetVirtualPath(physicalPath);