ASP.NET Core中Server.MapPath的等价物是什么?

Pro*_*ofK 23 asp.net asp.net-mvc asp.net-core-mvc asp.net-core

我在一些代码中有这行我想复制到我的控制器,但编译器抱怨

"服务器"名称在当前上下文中不存在

var UploadPath = Server.MapPath("~/App_Data/uploads")
Run Code Online (Sandbox Code Playgroud)

如何在ASP.NET Core中实现等效?

ash*_*hin 39

在Asp.NET Core中,托管环境已经使用IHostingEnvironment接口进行了抽象

ContentRootPath属性将让您使用的应用程序内容文件的绝对路径.

如果要访问可通过Web管理的根路径(默认情况下为www文件夹),也可以使用属性WebRootPath

您可以将此依赖项注入控制器并按如下方式访问它:

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 目前还不清楚OP的实际答案是什么?! (2认同)
  • 我讨厌依赖注入。不使用DI如何获取托管环境? (2认同)

Dar*_*eal 24

在大多数情况下,接受的答案的建议已经足够好了 - 因为它依赖于依赖注入- 仅限于控制器和视图:为了有一个Server.MapPath可以从非单例辅助类访问的适当替换,我们可以添加以下行(s)Configure()应用程序Startup.cs文件方法 末尾的代码:

// setup app's root folders
AppDomain.CurrentDomain.SetData("ContentRootPath", env.ContentRootPath);
AppDomain.CurrentDomain.SetData("WebRootPath", env.WebRootPath);
Run Code Online (Sandbox Code Playgroud)

这样我们就可以通过以下方式从任何类(包括但不限于控制器和视图)中检索它们:

var contentRootPath = (string)AppDomain.CurrentDomain.GetData("ContentRootPath");
var webRootPath = (string)AppDomain.CurrentDomain.GetData("WebRootPath");
Run Code Online (Sandbox Code Playgroud)

这可以被进一步利用来创建一个静态辅助方法,这将使我们拥有与旧的相同的功能Server.MapPath

public static class MyServer 
{
    public static string MapPath(string path)
    {
        return Path.Combine(
            (string)AppDomain.CurrentDomain.GetData("ContentRootPath"), 
            path);
    }
}
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式使用它:

var docPath = MyServer.MapPath("App_Data/docs");
Run Code Online (Sandbox Code Playgroud)

有关这种做法,有点背景的额外信息,看看这个职位上我的博客。

  • @RolandWales,如果您使用带有新托管模型的 ASP.NET Core 6(没有“Startup.cs”文件),则您的“env”变量等效(最初是“Startup.cs”中“Configure”方法的参数) ` class) 是 `builder.Environment` 属性(在 `Program.cs` 文件中)。 (7认同)
  • 注意:原始 .NET Framework Server.MapPath 的工作方式略有不同,当使用路径 =“\file.txt”调用时,返回 d:\website\file.txt,这仅返回“file.txt”。只需删除开头的“\”,即可获得类似的结果。希望有帮助 (2认同)
  • @joedotnot:“AppDomain.CurrentDomain”仍在 .NET 6 和 .NET 7 中工作,而其他方法(例如“AppDomain.SetCachePath”)已被弃用并且不再受支持。https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.currentdomain?view=net-7.0 (2认同)

小智 9

例如使用:var fullPath = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");

  • 这个答案不适用于Linux环境,请参阅/sf/ask/904134311/ (5认同)

ami*_*133 6

由于@ashin他的回答却IHostingEnvironment过时的。Net核心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
Run Code Online (Sandbox Code Playgroud)

新类型:

Microsoft.Extensions.Hosting.IHostEnvironment
Microsoft.AspNetCore.Hosting.IWebHostEnvironment : IHostEnvironment
Microsoft.Extensions.Hosting.IHostApplicationLifetime
Microsoft.Extensions.Hosting.Environments 
Run Code Online (Sandbox Code Playgroud)

因此,您必须使用IWebHostEnvironment而不是IHostingEnvironment。

public class HomeController : Controller
{
    private readonly IWebHostEnvironment _webHostEnvironment;

    public HomeController(IWebHostEnvironment webHostEnvironment)
    {
        _webHostEnvironment= webHostEnvironment;
    }

    public IActionResult Index()
    {
        string webRootPath = _webHostEnvironment.WebRootPath;
        string contentRootPath = _webHostEnvironment.ContentRootPath;

        return Content(webRootPath + "\n" + contentRootPath);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢amir133指出它...我已经更新了答案 (2认同)