如何在 asp.net core 中获取项目的根目录。 Directory.GetCurrentDirectory() 在 Mac 上似乎无法正常工作
Posted
技术标签:
【中文标题】如何在 asp.net core 中获取项目的根目录。 Directory.GetCurrentDirectory() 在 Mac 上似乎无法正常工作【英文标题】:How to get root directory of project in asp.net core. Directory.GetCurrentDirectory() doesn't seem to work correctly on a mac 【发布时间】:2017-09-28 07:27:39 【问题描述】:我的项目有一个文件夹结构:
项目, 项目/数据 项目/引擎 项目/服务器 项目/前端在服务器中(在 Project/Server 文件夹中运行)我指的是这样的文件夹:
var rootFolder = Directory.GetCurrentDirectory();
rootFolder = rootFolder.Substring(0,
rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length);
PathToData = Path.GetFullPath(Path.Combine(rootFolder, "Data"));
var Parser = Parser();
var d = new FileStream(Path.Combine(PathToData, $"dataFileName.txt"), FileMode.Open);
var fs = new StreamReader(d, Encoding.UTF8);
在我的 Windows 机器上,这段代码运行良好,因为 Directory.GetCurrentDirectory()
引用了当前文件夹,并且正在做
rootFolder.Substring(0, rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length);
获取项目的根文件夹(不是 bin 或 debug 文件夹)。
但是当我在 Mac 上运行它时,它得到“Directory.GetCurrentDirectory()
”将我发送到 /usr//[其他东西]。它没有引用我的项目所在的文件夹。
在我的项目中查找相对路径的正确方法是什么?我应该在哪里存储数据文件夹,以便解决方案中的所有子项目都可以轻松访问 - 特别是红隼服务器项目?我宁愿不必将其存储在 wwwroot 文件夹中,因为数据文件夹由团队中的其他成员维护,我只想访问最新版本。我有哪些选择?
【问题讨论】:
【参考方案1】:取决于您在红隼管道中的位置 - 如果您有权访问 IConfiguration
(Startup.cs
构造函数)或 IWebHostEnvironment
(以前为 IHostingEnvironment
) 您可以将IWebHostEnvironment
注入到您的构造函数中,也可以只从配置中请求密钥。
在Startup.cs
构造函数中注入IWebHostEnvironment
public Startup(IConfiguration configuration, IWebHostEnvironment env)
var contentRoot = env.ContentRootPath;
Using IConfiguration in Startup.cs Constructor
public Startup(IConfiguration configuration)
var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
【讨论】:
您可能可以将 IConfiguration 注入控制器,并从中获取您需要的内容。对吗? 我们如何在 Startup 中访问 contentRoot ? IHostingEnvironment 现在已过时 int Core ,并由 IWebHostEnvironment 取代 @AntonioRodríguez - 更新以反映,IWebHostEnvironment
实现 IHostEnvironment
- reference - IHostingEnvironment
has been retired【参考方案2】:
目前正在开发 .Net Core 2.2 和 3.0。
在控制器中获取项目根目录:
为宿主环境创建一个属性
private readonly IHostingEnvironment _hostingEnvironment;
将 Microsoft.AspNetCore.Hosting 添加到您的控制器
using Microsoft.AspNetCore.Hosting;
在构造函数中注册服务
public HomeController(IHostingEnvironment hostingEnvironment)
_hostingEnvironment = hostingEnvironment;
现在,获取项目根路径
string projectRootPath = _hostingEnvironment.ContentRootPath;
要获取“wwwroot”路径,请使用
_hostingEnvironment.WebRootPath
【讨论】:
这种方法也适用于 .Net Core 2.2 因为想要在开发模式下获取文件路径意味着从 Visual Studio 运行项目时“_hostingEnvironment.WebRootPath”和“hostingEnvironment.ContentRootPath”都返回空值。我应该怎么做才能得到文件路径 @maliksaifullah 检查您的wwwroot
是否在项目中并且它不为空。
@maliksaifullah 你能告诉我你的控制器你想在哪里找到路径吗?
@maliksaifullah 您是否在控制器中注册服务?我不认为IHostingEvironment
是在这里使用依赖注入注入的,这就是问题所在。【参考方案3】:
在某些情况下,_hostingEnvironment.ContentRootPath
和 System.IO.Directory.GetCurrentDirectory()
以源目录为目标。这是bug 关于它。
那里提出的解决方案帮助了我
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
【讨论】:
所有 .NET Core 应用程序都是一个控制台。 在核心应用程序中,这返回了“...\bin\Debug\netcoreapp\”,而不是预期的根项目文件夹。 @Roberto Root 网络核心应用程序的项目文件夹不应返回。这是正确的行为。【参考方案4】:如前所述(并撤回)。要获取 base 目录,就像在运行程序集的位置一样,不要使用 Directory.GetCurrentDirectory(),而是从 IHostingEnvironment.ContentRootPath 获取它。
private IHostingEnvironment _hostingEnvironment;
private string projectRootFolder;
public Program(IHostingEnvironment env)
_hostingEnvironment = env;
projectRootFolder = env.ContentRootPath.Substring(0,
env.ContentRootPath.LastIndexOf(@"\ProjectRoot\", StringComparison.Ordinal) + @"\ProjectRoot\".Length);
但是我犯了一个额外的错误:我在启动时将 ContentRoot 目录设置为 Directory.GetCurrentDirectory() 破坏了我想要的默认值! 在这里我注释掉了有问题的行:
public static void Main(string[] args)
var host = new WebHostBuilder().UseKestrel()
// .UseContentRoot(Directory.GetCurrentDirectory()) //<== The mistake
.UseIISIntegration()
.UseStartup<Program>()
.Build();
host.Run();
现在它运行正常 - 我现在可以导航到我的项目根目录的子文件夹:
var pathToData = Path.GetFullPath(Path.Combine(projectRootFolder, "data"));
我通过阅读BaseDirectory vs. Current Directory 和@CodeNotFound 发现了我的错误(由于上述错误而被撤回,因为它没有工作)基本上可以在这里找到:Getting WebRoot Path and Content Root Path in Asp.net Core
【讨论】:
仅供参考,如果您想知道如何在 Startup 类中获取 IHostingEnvironment:将其添加为构造函数参数。【参考方案5】:试试看这里:Best way to get application folder path
从那里引用:
System.IO.Directory.GetCurrentDirectory()
返回当前 目录,可能是也可能不是应用程序所在的文件夹 位于。 Environment.CurrentDirectory 也是如此。万一你 在 DLL 文件中使用它,它将返回 进程正在运行(在 ASP.NET 中尤其如此)。
【讨论】:
【参考方案6】:如果您使用的是 ASP.NET MVC Core 3 或更新版本,IHostingEnvironment
已被弃用并替换为 IWebHostEnvironment
public Startup(IWebHostEnvironment webHostEnvironment)
var webRootPath = webHostEnvironment.WebRootPath;
【讨论】:
从技术上讲,我相信IHostingEnvironment
已被IHostEnvironment
取代。 IWebHostEnvironment
是一个更具体的变体,特定于网络主机。库项目(甚至可以说是您自己的解决方案的类库)可能会很好地避免对 IWebHostEnvironment
的依赖,因为它们不能保证它们将在 web 主机中运行。【参考方案7】:
我用这段代码解决了这个问题:
using System.IO;
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.Substring(0, Assembly.GetEntryAssembly().Location.IndexOf("bin\\")))
【讨论】:
一个实际上可以理解且有效的答案。谢谢! 请不要使用这个答案,因为它硬编码了bin
,可能不存在!【参考方案8】:
如果这对任何人都有用,在 Razor 页面 cshtml.cs 文件中,获取方法如下:向构造函数添加 IHostEnvironment hostEnvironment
参数,它将自动注入:
public class IndexModel : PageModel
private readonly ILogger<IndexModel> _logger;
private readonly IHostEnvironment _hostEnvironment;
public IndexModel(ILogger<IndexModel> logger, IHostEnvironment hostEnvironment)
_logger = logger;
_hostEnvironment = hostEnvironment; // has ContentRootPath property
public void OnGet()
PS:IHostEnvironment
在 Microsoft.Extensions.Hosting
命名空间中,在 Microsoft.Extensions.Hosting.Abstractions.dll
... 真是一团糟!
【讨论】:
【参考方案9】:如果您不适合通过 DI 使用 IWebHostEnvironment
,请使用
AppContext.BaseDirectory
【讨论】:
不确定为什么两个选项给出不同的值。我寻找的正确的是 BaseDirectory。谢谢!【参考方案10】:基于 Henrique A 技术并支持单元测试上下文...
ReadOnlySpan<char> appPath = Assembly.GetEntryAssembly().Location.Replace("YOURTestProject", "YOUR");
var dir = Path.GetDirectoryName(appPath.Slice(0, appPath.IndexOf("bin\\")));
string path = Path.Combine(dir.ToString(), "Resources", "countries.dat");
if (System.IO.File.Exists(path))
countries = System.IO.File.ReadAllLines(path);
【讨论】:
【参考方案11】:似乎 IHostingEnvironment 已被 IHostEnvironment 取代 (和其他一些人)。您应该能够更改接口类型 你的代码和一切都会像以前一样工作:-)
您可以在 GitHub 上的此链接中找到有关更改的更多信息 https://github.com/aspnet/AspNetCore/issues/7749
EDIT 还有一个额外的接口 IWebHostEnvironment 可用于 ASP.NET Core 应用程序。这可在 Microsoft.AspNetCore.Hosting 命名空间。
参考:https://***.com/a/55602187/932448
【讨论】:
这是另一个答案的文字复制和粘贴。您应该将问题标记为重复,而不是复制内容。以上是关于如何在 asp.net core 中获取项目的根目录。 Directory.GetCurrentDirectory() 在 Mac 上似乎无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章
[Asp.Net Core]Asp.Net Core与配置系统的集成
[Asp.Net Core]Asp.Net Core与配置系统的集成
[Asp.Net Core]Asp.Net Core与配置系统的集成