如何在asp.net核心中获取项目的根目录.Directory.GetCurrentDirectory()似乎无法在mac上正常工作

akr*_*nes 42 c# asp.net-core

我的项目有一个文件夹结构:

  • 项目,
  • 项目/数据
  • 项目/发动机
  • 项目/服务器
  • 项目/前端

在服务器中(在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);
Run Code Online (Sandbox Code Playgroud)

在我的Windows机器上,这个代码工作正常,因为它被Directory.GetCurrentDirectory()引用到当前文件夹,并且正在执行

rootFolder.Substring(0, rootFolder.IndexOf(@"\Project\", StringComparison.Ordinal) + @"\Project\".Length); 
Run Code Online (Sandbox Code Playgroud)

获取项目的根文件夹(不是bin或debug文件夹).但当我在Mac上运行它时,它" Directory.GetCurrentDirectory()"将我发送到/ usr // [其他东西].它没有引用我的项目所在的文件夹.

在我的项目中找到相对路径的正确方法是什么?我应该在哪里存储数据文件夹,以便解决方案中的所有子项目都可以轻松访问 - 特别是对于Kestrel服务器项目?我更喜欢不必将它存储在wwwroot文件夹中,因为数据文件夹由团队中的其他成员维护,我只想访问最新版本.我有什么选择?

Sli*_*SFT 41

取决于您在kestrel管道中的位置 - 如果您有权访问IConfiguration(Startup.cs构造函数),或者IHostingEnvironment您可以将其IHostingEnvironment注入构造函数或只是从配置中请求密钥.

IHostingEnvironmentStartup.cs构造函数中注入

public Startup(IConfiguration configuration, IHostingEnvironment env)
{
     var contentRoot = env.ContentRootPath;
}
Run Code Online (Sandbox Code Playgroud)

在Startup.cs构造函数中使用IConfiguration

public Startup(IConfiguration configuration)
{
     var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
}
Run Code Online (Sandbox Code Playgroud)

  • IHostingEnvironment 现已过时 int Core ,并由 IWebHostEnvironment 取代 (5认同)
  • @AntonioRodríguez - 更新以反映“IWebHostEnvironment”实现了“IHostEnvironment” - [参考](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.iwebhostenvironment?view=aspnetcore-3.1 ) - [`IHostingEnvironment` 已退役](/sf/answers/3892153121/) (3认同)

Ste*_*nJM 37

到目前为止,正在使用.Net Core 2.2和3.0.

要在Controller中获取项目根目录:

要获得" wwwroot "路径,请使用

_hostingEnvironment.WebRootPath
Run Code Online (Sandbox Code Playgroud)

  • 这种方法对于.Net Core 2.2也很好用 (2认同)
  • 请改用“Microsoft.Extensions.Hosting”中的“IHostEnvironment”。请参阅[公告:IHostingEnvironment 和 IApplicationLifetime 已标记为过时并被替换](https://github.com/dotnet/aspnetcore/issues/7749)。 (2认同)

Dav*_*idG 18

如果您使用的是 ASP.NET MVC Core 3 或更新版本,IHostingEnvironment已弃用并替换为IWebHostEnvironment

public Startup(IWebHostEnvironment webHostEnvironment)
{
    var webRootPath = webHostEnvironment.WebRootPath;
}
Run Code Online (Sandbox Code Playgroud)


akr*_*nes 17

如前所述(并收回).要获取基本目录(如在运行程序集的位置),请不要使用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);
    }
Run Code Online (Sandbox Code Playgroud)

但是我又犯了一个错误:我在启动时将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();
    }
Run Code Online (Sandbox Code Playgroud)

现在它运行正常 - 我现在可以导航到我的项目root的子文件夹:

var pathToData = Path.GetFullPath(Path.Combine(projectRootFolder, "data"));
Run Code Online (Sandbox Code Playgroud)

我通过阅读BaseDirectory与当前目录以及@CodeNotFound创建的答案(由于上述错误导致其无法正常工作而实现了收回)实现了我的错误,基本上可以在这里找到:在Asp.net中获取WebRoot路径和内容根路径核心

  • 仅供参考,如果您想知道如何在Startup类中获取IHostingEnvironment:将其添加为构造函数参数. (6认同)

ale*_*eha 13

在某些情况下_hostingEnvironment.ContentRootPathSystem.IO.Directory.GetCurrentDirectory()源目录的目标.这是关于它的错误.

那里提出的解决方案帮助了我

Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
Run Code Online (Sandbox Code Playgroud)

  • 在核心应用程序中,这返回“...\bin\Debug\netcoreapp\”,而不是预期的根项目文件夹。 (2认同)
  • @Roberto 不应返回网络核心应用程序的根项目文件夹。这是正确的行为。 (2认同)

shl*_*gug 12

试试这里:获取应用程序文件夹路径的最佳方法

从那里引用:

System.IO.Directory.GetCurrentDirectory()返回当前目录,该目录可能是也可能不是应用程序所在的文件夹.Environment.CurrentDirectory也是如此.如果您在DLL文件中使用它,它将返回进程运行的路径(在ASP.NET中尤其如此).


小智 12

我用这段代码解决了这个问题:

using System.IO;

var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.Substring(0, Assembly.GetEntryAssembly().Location.IndexOf("bin\\")))
Run Code Online (Sandbox Code Playgroud)

  • 请不要使用这个答案,因为它硬编码了可能不存在的“bin”! (3认同)

Cha*_*nds 9

我在asp.net core 6上进行了测试和比较,我认为这可以帮助别人。

假设你的项目位置路径是D:\Project\Server,如果你使用linux或mac只需替换\/.

var app = builder.Build();
IWebHostEnvironment environment = app.Environment;

System.Console.WriteLine(environment.ContentRootPath);
// D:\Project\Server\
System.Console.WriteLine(environment.WebRootPath);
// D:\Project\Server\wwwroot

System.Console.WriteLine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
// D:\Project\Server\bin\Debug\net6.0
System.Console.WriteLine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase));
// file:\D:\Project\Server\bin\Debug\net6.0
System.Console.WriteLine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
// D:\Project\Server\bin\Debug\net6.0

System.Console.WriteLine(Directory.GetCurrentDirectory());
// D:\Project\Server
System.Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
// D:\Project\Server\bin\Debug\net6.0\
System.Console.WriteLine(AppContext.BaseDirectory);
// D:\Project\Server\bin\Debug\net6.0\
Run Code Online (Sandbox Code Playgroud)

注意:如果environment.WebRootPath是空字符串,则需要wwwroot在根项目中创建文件夹,然后一切正常。


Ale*_*lex 6

如果使用IWebHostEnvironmentvia DI 不适合您,请使用

AppContext.BaseDirectory
Run Code Online (Sandbox Code Playgroud)