【问题标题】:What is the equivalent of Server.MapPath in ASP.NET Core?ASP.NET Core 中的 Server.MapPath 等价物是什么?
【发布时间】:2018-08-30 03:18:49
【问题描述】:

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

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

var UploadPath = Server.MapPath("~/App_Data/uploads")

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

【问题讨论】:

标签: asp.net asp.net-mvc asp.net-core asp.net-core-mvc


【解决方案1】:

更新:IHostingEnvironment 已弃用。请参阅下面的更新。

在 Asp.NET Core 2.2 及以下版本中,托管环境已使用接口进行抽象,IHostingEnvironment

ContentRootPath 属性将使您能够访问应用程序内容文件的绝对路径。

如果您想访问 web-servable 根路径(默认为 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);
        }
    }

更新 - .NET CORE 3.0 及更高版本

正如@amir133 所指出的,IHostingEnvironment 已被 .NET Core 3.0 标记为过时。您应该使用IWebHostEnvironment 而不是IHostingEnvironment。请参考那个答案below

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如何获取托管环境?
  • 刚刚在尝试更新网站以获取新内容时遇到了这个问题。为什么这样做?在我看来,这当然不那么直观。事实上,微软让开发变得有趣的日子似乎已经一去不复返了。现在,所有代码看起来都像是不想写下所有代码的新一代孩子的某种黑客工作。
【解决方案2】:

.Net 6(.NetCore 3 及以上)

例如我要定位~/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


.Net Core 2

例如我要定位~/wwwroot/CSS

public class YourController : Controller
{
    private readonly IHostingEnvironment _HostEnvironment; //diference is here : IHostingEnvironment  vs I*Web*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 核心 3 中已过时!!

根据this

过时类型(警告):

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 的答案?
  • 不知道怎么注入这个?实现类在哪里?
  • @vesa 在启动时将其注入配置
【解决方案3】:

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

【讨论】:

【解决方案4】:

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

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

有关此方法的更多信息和一些背景知识,请查看我博客上的 this post

【讨论】:

  • 并非所有英雄都穿着斗篷!
  • 注意:原始的 .NET Framework Server.MapPath 在使用 path = "\file.txt" 调用时返回 d:\website\file.txt 的工作方式略有不同,它只返回 "file.txt"。文本文件”。只需删除初始的“\”,即可获得类似的结果。希望有帮助
猜你喜欢
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
相关资源
最近更新 更多