Microsoft Web API: как вы делаете Server.MapPath?

239

Поскольку Microsoft Web API не MVC , вы не можете сделать что-то вроде этого:

var a = Request.MapPath("~");

ни это

var b = Server.MapPath("~");

потому что они находятся в System.Webпространстве имен, а не в System.Web.Httpпространстве имен.

Так как же определить относительный путь к серверу в Web API ?
Я делал что-то подобное в MVC :

var myFile = Request.MapPath("~/Content/pics/" + filename);

Который дал бы мне абсолютный путь на диске:

"C:\inetpub\wwwroot\myWebFolder\Content\pics\mypic.jpg"
Захари Скотт
источник

Ответы:

470

Вы можете использовать HostingEnvironment.MapPath в любом контексте, гдеSystem.Web подобные объекты HttpContext.Currentнедоступны (например, также из статического метода).

var mappedPath = System.Web.Hosting.HostingEnvironment.MapPath("~/SomePath");

Смотрите также В чем разница между Server.MapPath и HostingEnvironment.MapPath?

StuartLC
источник
1
Это хорошо, но не существует простого способа издеваться над HostingEnvironment, так как это статический экземпляр класса ... :-(
Джош Г
6
Конечно, но в вашем контроллере или другом логическом слое, который вы хотите протестировать, вы бы взяли только зависимость от вашей собственной абстракции, например IPathMapper(вы, вероятно, свернете это с кучей других проблем в больший интерфейс toolbelt / utility) с методом string MapPath(string virtualPath). Только конкретная реализация, о которой вам WebApi IPathMapperнужно знатьSystem.Web.Hosting.HostingEnvironment
StuartLC
1
@JoshG - вы можете абстрагировать HostingEnvironment.MapPath через Func <string, string> GetWebPath = HostingEnvironment.MapPath, а затем переписать GetWebPath во время теста с помощью макета.
Шон Б
Похоже, что это имеет проблемы с относительными путями, как../images/
AaA
Он дает путь к контроллеру, поэтому я могу получить путь к сервису, используя «HostingEnvironment»?
Аслам
13
string root = HttpContext.Current.Server.MapPath("~/App_Data");
ArgeKumandan
источник
16
Вы не хотите использовать HttpContext.Current в WebAPI. А как насчет собственных API? Вы не можете полагаться на HttpContext.Current, чтобы быть там. Также это не тест дружественных.
Тревор де Коеккук
2

В дополнение к тем, кто сталкивается с этим, один хороший способ запустить тестовый уровень при использовании вызова HostingEnvironment, если при доступе, скажем, к общему ресурсу UNC: \ example \, сопоставленному с ~ / example /, вы можете выполнить это, чтобы обойти Вопросы IIS-Express:

#if DEBUG
    var fs = new FileStream(@"\\example\file",FileMode.Open, FileAccess.Read);
#else
    var fs = new FileStream(HostingEnvironment.MapPath("~/example/file"), FileMode.Open, FileAccess.Read);
#endif

Я считаю, что это полезно, если у вас есть права на локальное тестирование файла, но вам нужно сопоставление env после запуска.

Натан Тиг
источник
Кстати, HostingEnvironmentкласс находится в System.Web.Hostingпространстве имен.
Дермот
2
Какая альтернатива HostingEnvironment для ядра DNX 5.0?
Ройдуккей
Новый класс Startup.cs теперь внедряет общедоступный Startup (IHostingEnvironment env) {} в конструкцию, свойство просто забывает, просто сделал это на днях. это позволяет вам также управлять средой для каждого экземпляра, а с помощью директив #if создать приложение, которое может легко выполнять межуровневое развертывание в нескольких средах.
Натан Тиг
1

Я не могу сказать из контекста, который вы предоставляете, но если это то, что вам просто нужно сделать при запуске приложения, вы все равно можете использовать Server.MapPathв WebApiHttpApplication; например, в Application_Start().

Я просто отвечаю на ваш прямой вопрос; уже упоминавшееся HostingEnvironment.MapPath(), вероятно, является предпочтительным решением.

скотча
источник
0

Так Server.MapPath()как не существует внутри Web Api (Soap или REST), вам нужно будет обозначить локальный относительно каталога context-home веб-сервера. Самый простой способ сделать это с помощью:

string AppContext.BaseDirectory { get;}

Затем вы можете использовать это для объединения строки пути для сопоставления относительного пути с любым файлом.
ПРИМЕЧАНИЕ: пути к строкам \не /такие, как в mvc.

Пример:

System.IO.File.Exists($"{**AppContext.BaseDirectory**}\\\\Content\\\\pics\\\\{filename}");

возвращает true, утверждая, что это звуковой путь в вашем примере

гость
источник
-1

Выбранный ответ не работает в моем приложении Web API. Я должен был использовать

System.Web.HttpRuntime.AppDomainAppPath
Zoomzoom
источник
1
Хотя кажется, что это единственный способ получить путь к вашему приложению WebApi, это дает вам корень вашего приложения, но не переводит относительные пути, такие как ~\folderили ../images/физические пути
AaA
-1

Вы можете попробовать как:

var path = "~ / Image / test.png"; System.Web.Hosting.HostingEnvironment.MapPath (@ + путь)

САНДИП Г.ПАТИЛЬ
источник