Вопрос

Если мне удалось найти и проверить существование файла с помощью Server.MapPath, и теперь я хочу отправить пользователя непосредственно к этому файлу, что делать? самый быстрый способ преобразовать этот абсолютный путь обратно в относительный веб-путь?

Это было полезно?

Решение

Возможно, это сработает:

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

Я использую С#, но его можно адаптировать к VB.

Другие советы

Разве не было бы неплохо иметь Server.RelativePath(путь)?

ну, надо просто продлить ;-)

public static class ExtensionMethods
{
    public static string RelativePath(this HttpServerUtility srv, string path, HttpRequest context)
    {
        return path.Replace(context.ServerVariables["APPL_PHYSICAL_PATH"], "~/").Replace(@"\", "/");
    }
}

При этом вы можете просто позвонить

Server.RelativePath(path, Request);

Я знаю, что это устарело, но мне нужно было учитывать виртуальные каталоги (согласно комментарию @Costo).Кажется, это помогает:

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

Мне нравится идея Каноаса.К сожалению, у меня не было доступного «HttpContext.Current.Request» (BundleConfig.cs).

Я изменил метод следующим образом:

public static string RelativePath(this HttpServerUtility srv, string path)
{
     return path.Replace(HttpContext.Current.Server.MapPath("~/"), "~/").Replace(@"\", "/");
}

Если вы использовали Server.MapPath, у вас уже должен быть относительный веб-путь.Согласно Документация MSDN, этот метод принимает одну переменную, путь, который является виртуальным путем веб-сервера.Таким образом, если вы смогли вызвать метод, у вас уже должен быть сразу же доступен относительный веб-путь.

Для ядра asp.net я написал вспомогательный класс, чтобы получать пути в обоих направлениях.

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

из контроллера или службы внедрите FilePathHelper и используйте:

var physicalPath = _fp.GetPhysicalPath("/img/banners/abro.png");

и наоборот

var virtualPath = _fp.GetVirtualPath(physicalPath);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top