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?


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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.