У меня есть эта строка в каком-то коде, который я хочу скопировать в свой контроллер, но компилятор жалуется, что
The name 'Server' does not exist in the current context
var UploadPath = Server.MapPath("~/App_Data/uploads")
Как я могу достичь эквивалента в ASP.NET Core?
ОБНОВЛЕНИЕ: IHostingEnvironment устарел. См. Обновление ниже.
В Asp.NET Core 2.2 и ниже среда размещения была абстрагирована с помощью интерфейса IHostingEnvironment
Свойство ContentRootPath предоставит вам доступ к абсолютному пути к файлам содержимого приложения.
Вы также можете использовать свойство WebRootPath, если хотите получить доступ к корневому пути, обслуживаемому через Интернет (по умолчанию папка www)
Вы можете внедрить эту зависимость в свой контроллер и получить к ней доступ следующим образом:
public class HomeController : Controller
{
private readonly IHostingEnvironment _hostingEnvironment;
public HomeController(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}
public ActionResult Index()
{
string webRootPath = _hostingEnvironment.WebRootPath;
string contentRootPath = _hostingEnvironment.ContentRootPath;
return Content(webRootPath + "\n" + contentRootPath);
}
}
ОБНОВЛЕНИЕ - .NET CORE 3.0 и выше
IHostingEnvironment была помечена как устаревшая с .NET Core 3.0, как указано @ amir133. Вы должны использовать IWebHostEnvironment вместо IHostingEnvironment. Пожалуйста, обратитесь к этому ответу ниже.
Microsoft аккуратно разделила свойства среды хоста между этими интерфейсами. См. Определение интерфейса ниже:
namespace Microsoft.Extensions.Hosting
{
public interface IHostEnvironment
{
string EnvironmentName { get; set; }
string ApplicationName { get; set; }
string ContentRootPath { get; set; }
IFileProvider ContentRootFileProvider { get; set; }
}
}
namespace Microsoft.AspNetCore.Hosting
{
public interface IWebHostEnvironment : IHostEnvironment
{
string WebRootPath { get; set; }
IFileProvider WebRootFileProvider { get; set; }
}
}
Я отредактировал это, чтобы вы не копировали ответ @ aamir133.
Спасибо .. Фактически, я не копировал код aamir, я скопировал свой первоначальный ответ и заменил интерфейс. :) Но то, что вы сказали, имеет смысл, я снова отредактировал и просто связал ответ с ответом aamir, а также предоставил определение интерфейса для людей, которым интересно знать, как свойства расположены между этими интерфейсами ..
Непонятно, каков фактический ответ на OP ?!
Ненавижу внедрение зависимостей. Как я могу получить среду хостинга без использования DI?
Просто столкнулся с этим, пытаясь обновить сайт, чтобы добавить новый контент. Почему это было сделано? Мне это определенно кажется менее интуитивным. На самом деле, похоже, прошли те времена, когда Microsoft развлекала разработку. Теперь весь код кажется чем-то вроде хакерской работы со стороны детей нового поколения, которые не хотят писать весь код.
Например, я хочу найти ~/wwwroot/CSS
public class YourController : Controller
{
private readonly IWebHostEnvironment _webHostEnvironment;
public YourController (IWebHostEnvironment webHostEnvironment)
{
_webHostEnvironment= webHostEnvironment;
}
public IActionResult Index()
{
string webRootPath = _webHostEnvironment.WebRootPath;
string contentRootPath = _webHostEnvironment.ContentRootPath;
string path = "";
path = Path.Combine(webRootPath , "CSS");
//or path = Path.Combine(contentRootPath , "wwwroot" ,"CSS" );
return View();
}
}
Также, если у вас нет контроллера или службы, следуйте последней части и зарегистрируйте его класс как одноэлементный. Затем в Startup.ConfigureServices:
services.AddSingleton<your_class_Name>();
Наконец, введите your_class_Name
там, где он вам нужен.
Например, я хочу найти ~/wwwroot/CSS
public class YourController : Controller
{
private readonly IHostingEnvironment _HostEnvironment;
public YourController (IHostingEnvironment HostEnvironment)
{
_HostEnvironment= HostEnvironment;
}
public ActionResult Index()
{
string webRootPath = _HostEnvironment.WebRootPath;
string contentRootPath = _HostEnvironment.ContentRootPath;
string path = "";
path = Path.Combine(webRootPath , "CSS");
//or path = Path.Combine(contentRootPath , "wwwroot" ,"CSS" );
return View();
}
}
Спасибо @Ashin, но IHostingEnvironment
устарел в MVC core 3 !!
согласно это:
Устаревшие типы (предупреждение):
Microsoft.Extensions.Hosting.IHostingEnvironment
Microsoft.AspNetCore.Hosting.IHostingEnvironment
Microsoft.Extensions.Hosting.IApplicationLifetime
Microsoft.AspNetCore.Hosting.IApplicationLifetime
Microsoft.Extensions.Hosting.EnvironmentName
Microsoft.AspNetCore.Hosting.EnvironmentName
Новые типы:
Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments
Поэтому вы должны использовать IWebHostEnvironment
вместо IHostingEnvironment
.
Спасибо amir133 за указание .. я обновил ответ
@ashin Вы обновили ответ, чтобы написать именно то, что написал amir133. Почему бы просто не упомянуть вместо этого ссылку на ответ amir133?
используйте, например: var fullPath = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
этот ответ не будет работать для среды Linux, см. stackoverflow.com/questions/12916204/…
Спасибо за комментарий, не знала
Предложение принятого ответа достаточно хорошо в большинстве сценариев, однако - поскольку оно зависит от Внедрение зависимости - ограничено контроллерами и представлениями: для того, чтобы иметь правильную замену Server.MapPath
, к которой можно получить доступ из не-одноэлементных вспомогательных классов, мы можем добавить следующую строку (s) кода в конце метода Configure()
файла Startup.cs
приложения:
// setup app's root folders
AppDomain.CurrentDomain.SetData("ContentRootPath", env.ContentRootPath);
AppDomain.CurrentDomain.SetData("WebRootPath", env.WebRootPath);
Таким образом, мы сможем получить их из любого класса (включая, но не ограничиваясь, контроллеры и представления) следующим образом:
var contentRootPath = (string)AppDomain.CurrentDomain.GetData("ContentRootPath");
var webRootPath = (string)AppDomain.CurrentDomain.GetData("WebRootPath");
В дальнейшем это можно использовать для создания статического вспомогательного метода, который позволит нам иметь ту же функциональность, что и старый добрый Server.MapPath
:
public static class MyServer
{
public static string MapPath(string path)
{
return Path.Combine(
(string)AppDomain.CurrentDomain.GetData("ContentRootPath"),
path);
}
}
Что можно использовать следующим образом:
var docPath = MyServer.MapPath("App_Data/docs");
Для получения дополнительной информации об этом подходе и немного предыстории, взгляните на эта почта в моем блоге.
Используйте
IHostingEnvironment.WebRootPath
, а затем используйтеPath.Combine
со вторым аргументом, назначенным целевому каталогу. См. Эквивалент Server.MapPath в ASP.NET Core для получения дополнительной информации.