mvc - server.mappath c# windows forms
Ruta absoluta de regreso a la ruta relativa a la web (6)
Si he logrado localizar y verificar la existencia de un archivo usando Server.MapPath y ahora quiero enviar al usuario directamente a ese archivo, ¿cuál es la forma más rápida de convertir esa ruta absoluta en una ruta web relativa?
¿No sería bueno tener Server.RelativePath (ruta) ?
bueno, solo necesitas extenderlo ;-)
public static class ExtensionMethods
{
public static string RelativePath(this HttpServerUtility srv, string path, HttpRequest context)
{
return path.Replace(context.ServerVariables["APPL_PHYSICAL_PATH"], "~/").Replace(@"/", "/");
}
}
Con esto simplemente puedes llamar
Server.RelativePath(path, Request);
Me gusta la idea de Canoas. Lamentablemente no tenía "HttpContext.Current.Request" disponible (BundleConfig.cs).
Cambié el método así:
public static string RelativePath(this HttpServerUtility srv, string path)
{
return path.Replace(HttpContext.Current.Server.MapPath("~/"), "~/").Replace(@"/", "/");
}
Para asp.net core escribí una clase de ayuda para obtener parches en ambas direcciones.
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");
}
desde el controlador o servicio inyecte FilePathHelper y use:
var physicalPath = _fp.GetPhysicalPath("/img/banners/abro.png");
y viceversa
var virtualPath = _fp.GetVirtualPath(physicalPath);
Quizás esto podría funcionar:
String RelativePath = AbsolutePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);
Estoy usando c # pero podría adaptarse a vb.
Sé que esto es antiguo, pero necesitaba tener en cuenta los directorios virtuales (según el comentario de @ Costo). Esto parece ayudar:
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.");
}
Si usó Server.MapPath, entonces ya debería tener la ruta web relativa. De acuerdo con la documentación de MSDN , este método toma una variable, ruta , que es la ruta virtual del servidor web. Entonces, si pudo llamar al método, ya debería tener la ruta web relativa inmediatamente accesible.