私のプロジェクトには、次のようなフォルダ構造があります。
サーバー(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フォルダーに保存する必要はなく、最新バージョンにアクセスしたいだけです。私のオプションは何ですか?
Kestrelパイプラインのどこにいるかに応じて-IConfiguration
(Startup.cs
constructor)またはIHostingEnvironment
にアクセスできる場合は、IHostingEnvironment
を注入できます。コンストラクタに入力するか、設定からキーを要求するだけです。
Startup.cs
コンストラクターにIHostingEnvironment
を挿入しますpublic Startup(IConfiguration configuration, IHostingEnvironment env)
{
var contentRoot = env.ContentRootPath;
}
public Startup(IConfiguration configuration)
{
var contentRoot = configuration.GetValue<string>(WebHostDefaults.ContentRootKey);
}
.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
前述のとおり(および撤回)。実行中のアセンブリの場所のように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パスとコンテンツルートパスを取得
場合によっては、_hostingEnvironment.ContentRootPath
およびSystem.IO.Directory.GetCurrentDirectory()
がソースディレクトリをターゲットにします。これは bug です。
そこで提案された解決策は私を助けました
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
ここを見てみてください: アプリケーションフォルダーパスを取得する最良の方法
そこから引用するには:
System.IO.Directory.GetCurrentDirectory()
は、現在のディレクトリを返します。このディレクトリは、アプリケーションが置かれているフォルダである場合とそうでない場合があります。 Environment.CurrentDirectoryについても同様です。 DLLファイルでこれを使用している場合、プロセスが実行されている場所のパスを返します(これは特にASP.NETで当てはまります)。
このコードで問題を解決しました:
using System.IO;
var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location.Substring(0, Assembly.GetEntryAssembly().Location.IndexOf("bin\\")))