Pregunta

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 el lo más rápido ¿Manera de convertir esa ruta absoluta nuevamente en una ruta web relativa?

¿Fue útil?

Solución

Quizás esto podría funcionar:

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

Estoy usando c# pero podría adaptarlo a vb.

Otros consejos

¿No sería bueno tener Servidor.RelativePath(ruta)?

bueno, sólo necesitas ampliarlo ;-)

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 puedes simplemente llamar

Server.RelativePath(path, Request);

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.");
}

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(@"\", "/");
}

Si utilizó 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, camino, que es la ruta virtual del servidor web.Entonces, si pudo llamar al método, ya debería tener acceso inmediato a la ruta web relativa.

Para asp.net core, escribí una clase de ayuda para obtener rutas 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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top