public string GetWebAppFilePath(string relativePath)
{
if (HttpContext.Current == null)
throw new InvalidOperationException("非 Web 執行緒上下文,無 HttpContext");
string basePath = HttpContext.Current.Request.PhysicalApplicationPath; // 結尾含 \
return Path.Combine(basePath, relativePath.TrimStart('\\', '/'));
}
// 使用範例
string xmlPath = GetWebAppFilePath(@"App_Data\Config\settings.xml");
// 實際路徑: C:\inetpub\wwwroot\MyApp\App_Data\Config\settings.xml
public string GetAppBaseFilePath(string relativePath)
{
string basePath = AppDomain.CurrentDomain.BaseDirectory; // 結尾含 \
return Path.Combine(basePath, relativePath.TrimStart('\\', '/'));
}
// 使用範例
string logPath = GetAppBaseFilePath(@"Logs\app.log");
// 實際路徑: D:\MyApp\bin\Debug\Logs\app.log (或 Release/部署路徑)
public static string GetAbsolutePath(string relativePath)
{
if (string.IsNullOrEmpty(relativePath)) throw new ArgumentException("相對路徑不可為空");
string basePath;
if (HttpContext.Current != null)
basePath = HttpContext.Current.Request.PhysicalApplicationPath;
else
basePath = AppDomain.CurrentDomain.BaseDirectory;
// 正規化路徑分隔符
relativePath = relativePath.Replace('/', Path.DirectorySeparatorChar).TrimStart(Path.DirectorySeparatorChar);
return Path.Combine(basePath, relativePath);
}
public void WriteConfigFile(string relativePath, string content)
{
string fullPath = GetAbsolutePath(relativePath);
string dir = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
File.WriteAllText(fullPath, content, Encoding.UTF8);
Console.WriteLine($"已寫入: {fullPath}");
}
| 問題 | 原因 | 解決 |
|---|---|---|
| HttpContext.Current 為 null | 在非 Request 執行緒 (背景工作、Timer、啟動事件) | 啟動時儲存 BaseDirectory 到靜態變數,或傳入 IHostingEnvironment (ASP.NET Core) |
| BaseDirectory 指向錯誤資料夾 | 透過影子複製、測試執行器、ClickOnce 部署導致 | 用 `Assembly.GetExecutingAssembly().Location` 取得 DLL 實際位置再推導 |
| 權限不足無法寫入 | Program Files、System32 等受保護目錄 | 改寫 `Environment.GetFolderPath(SpecialFolder.LocalApplicationData)` 或 `AppDomain.CurrentDomain.GetData("DataDirectory")` |
// 註冊 IWebHostEnvironment / IHostEnvironment
public class MyService
{
private readonly IWebHostEnvironment _env;
public MyService(IWebHostEnvironment env) => _env = env;
public string GetPath(string relative) => Path.Combine(_env.ContentRootPath, relative);
}
原文連結:https://www.bianceng.cn/Programming/csharp/201410/45573.htm