Como faço para converter um caminho de arquivo em uma URL no ASP.NET
Pergunta
Basicamente, tenho um código para verificar um diretório específico para ver se existe uma imagem e, em caso afirmativo, quero atribuir uma URL à imagem a um ImageControl.
if (System.IO.Directory.Exists(photosLocation))
{
string[] files = System.IO.Directory.GetFiles(photosLocation, "*.jpg");
if (files.Length > 0)
{
// TODO: return the url of the first file found;
}
}
Solução
Pelo que eu sei, não existe um método para fazer o que você deseja;pelo menos não diretamente.eu armazenaria o photosLocation
como um caminho relativo ao aplicativo;por exemplo: "~/Images/"
.Dessa forma, você poderia usar MapPath para obter a localização física e ResolveUrl
para obter o URL (com um pouco de ajuda de System.IO.Path
):
string photosLocationPath = HttpContext.Current.Server.MapPath(photosLocation);
if (Directory.Exists(photosLocationPath))
{
string[] files = Directory.GetFiles(photosLocationPath, "*.jpg");
if (files.Length > 0)
{
string filenameRelative = photosLocation + Path.GetFilename(files[0])
return Page.ResolveUrl(filenameRelative);
}
}
Outras dicas
isso é o que eu uso:
private string MapURL(string path)
{
string appPath = Server.MapPath("/").ToLower();
return string.Format("/{0}", path.ToLower().Replace(appPath, "").Replace(@"\", "/"));
}
O problema com todas essas respostas é que elas não levam em consideração os diretórios virtuais.
Considerar:
Site named "tempuri.com/" rooted at c:\domains\site
virtual directory "~/files" at c:\data\files
virtual directory "~/files/vip" at c:\data\VIPcust\files
Então:
Server.MapPath("~/files/vip/readme.txt")
= "c:\data\VIPcust\files\readme.txt"
Mas existe não maneira de fazer isso:
MagicResolve("c:\data\VIPcust\files\readme.txt")
= "http://tempuri.com/files/vip/readme.txt"
porque não há como obter uma lista completa de diretórios virtuais.
Aceitei a resposta de Fredriks, pois parece resolver o problema com o mínimo de esforço, mas o objeto Request não parece conter o método ResolveUrl.Isso pode ser acessado através do objeto Page ou de um objeto de controle Image:
myImage.ImageUrl = Page.ResolveUrl(photoURL);
myImage.ImageUrl = myImage.ResolveUrl(photoURL);
Uma alternativa, se você estiver usando uma classe estática como eu, é usar o VirtualPathUtility:
myImage.ImageUrl = VirtualPathUtility.ToAbsolute(photoURL);
Talvez esta não seja a melhor maneira, mas funciona.
// Here is your path
String p = photosLocation + "whatever.jpg";
// Here is the page address
String pa = Page.Request.Url.AbsoluteUri;
// Take the page name
String pn = Page.Request.Url.LocalPath;
// Here is the server address
String sa = pa.Replace(pn, "");
// Take the physical location of the page
String pl = Page.Request.PhysicalPath;
// Replace the backslash with slash in your path
pl = pl.Replace("\\", "/");
p = p.Replace("\\", "/");
// Root path
String rp = pl.Replace(pn, "");
// Take out same path
String final = p.Replace(rp, "");
// So your picture's address is
String path = sa + final;
Editar:Ok, alguém marcou como não útil.Alguma explicação:pegue o caminho físico da página atual, divida-o em duas partes:servidor e diretório (como c:\inetpub\whatever.com\whatever) e nome da página (como /Whatever.aspx).O caminho físico da imagem deve conter o caminho do servidor, então "subtraia-os", deixando apenas o caminho da imagem relativo ao do servidor (como:\design\imagem.jpg).Substitua as barras invertidas por barras e anexe-as ao URL do servidor.
Isso funcionou para mim:
HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + HttpRuntime.AppDomainAppVirtualPath + "ImageName";
Até onde eu sei, não existe uma função única que faça isso (talvez você estivesse procurando o inverso de MapPath?).Eu adoraria saber se tal função existe.Até então, eu apenas pegaria o(s) nome(s) de arquivo retornado(s) por GetFiles, removeria o caminho e acrescentaria a raiz do URL.Isso pode ser feito genericamente.
A solução simples parece ser ter um local temporário no site que você possa acessar facilmente com URL e então mover os arquivos para o local físico quando precisar salvá-los.
Para obter a parte esquerda do URL:
?HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority)
"http://localhost:1714"
Para obter o nome do aplicativo (web):
?HttpRuntime.AppDomainAppVirtualPath
"/"
Com isso, você está disponível para adicionar seu caminho relativo e obter a URL completa.
Eu acho que isso deve funcionar.Pode estar errado nas barras.Não tenho certeza se eles são necessários ou não.
string url = Request.ApplicationPath + "/" + photosLocation + "/" + files[0];