web-dev-qa-db-ja.com

asp.netコアでプロジェクトのルートディレクトリを取得する方法。 Directory.GetCurrentDirectory()がMacで正しく動作しないようです

私のプロジェクトには、次のようなフォルダ構造があります。

  • 事業、
  • プロジェクト/データ
  • プロジェクト/エンジン
  • プロジェクト/サーバー
  • プロジェクト/フロントエンド

サーバー(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 // [他の何か]に送られました。私のプロジェクトがあるフォルダを参照していませんでした。

私のプロジェクトで相対パスを見つける正しい方法は何ですか?ソリューション内のすべてのサブプロジェクト、特にkestrelサーバープロジェクトに簡単にアクセスできるように、データフォルダーをどこに保存する必要がありますか?データフォルダーはチーム内の別のメンバーによって管理されているため、wwwrootフォルダーに保存する必要はなく、最新バージョンにアクセスしたいだけです。私のオプションは何ですか?

35
akraines

Kestrelパイプラインのどこにいるかに応じて-IConfigurationStartup.cs constructor)またはIHostingEnvironmentにアクセスできる場合は、IHostingEnvironmentを注入できます。コンストラクタに入力するか、設定からキーを要求するだけです。

Startup.csコンストラクターにIHostingEnvironmentを挿入します

public Startup(IConfiguration configuration, IHostingEnvironment env)
{
     var contentRoot = env.ContentRootPath;
}

Startup.csコンストラクターでIConfigurationを使用

public Startup(IConfiguration configuration)
{
     var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
}
32

.Net Core 2.2および3.0の現在の作業中

Controller:内でプロジェクトのルートディレクトリを取得するには

  • ホスティング環境のプロパティを作成する

    private readonly IHostingEnvironment _hostingEnvironment;
    
  • Microsoft.AspNetCore.Hostingをコントローラーに追加します

    using Microsoft.AspNetCore.Hosting;
    
  • コンストラクターでサービスを登録する

    public HomeController(IHostingEnvironment hostingEnvironment) {
        _hostingEnvironment = hostingEnvironment;
    }
    
  • 次に、プロジェクトのルートパスを取得します

    string projectRootPath = _hostingEnvironment.ContentRootPath;
    

wwwroot」パスを取得するには、使用します

_hostingEnvironment.WebRootPath
34
StefanJM

前述のとおり(および撤回)。実行中のアセンブリの場所のように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を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が答えを見つけてミスを認識しました(@CodeNotFoundは、上記のミスのために動作しなかったため撤回されました)。基本的にここにあります: Asp.net CoreでWebRootパスとコンテンツルートパスを取得

16
akraines

場合によっては、_hostingEnvironment.ContentRootPathおよびSystem.IO.Directory.GetCurrentDirectory()がソースディレクトリをターゲットにします。これは bug です。

そこで提案された解決策は私を助けました

Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
13
aleha

ここを見てみてください: アプリケーションフォルダーパスを取得する最良の方法

そこから引用するには:

System.IO.Directory.GetCurrentDirectory()は、現在のディレクトリを返します。このディレクトリは、アプリケーションが置かれているフォルダである場合とそうでない場合があります。 Environment.CurrentDirectoryについても同様です。 DLLファイルでこれを使用している場合、プロセスが実行されている場所のパスを返します(これは特にASP.NETで当てはまります)。

9
shlgug

このコードで問題を解決しました:

using System.IO;

var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.Substring(0, Assembly.GetEntryAssembly().Location.IndexOf("bin\\")))
1
Henrique A