为啥 AppDomain.CurrentDomain.BaseDirectory 在 asp.net 应用程序中不包含“bin”?
Posted
技术标签:
【中文标题】为啥 AppDomain.CurrentDomain.BaseDirectory 在 asp.net 应用程序中不包含“bin”?【英文标题】:Why AppDomain.CurrentDomain.BaseDirectory not contains "bin" in asp.net app?为什么 AppDomain.CurrentDomain.BaseDirectory 在 asp.net 应用程序中不包含“bin”? 【发布时间】:2012-01-29 23:42:36 【问题描述】:我有一个类似的网络项目:
namespace Web
public partial class _Default : System.Web.UI.Page
protected void Page_Load(object sender, EventArgs e)
lbResult.Text = PathTest.GetBasePath();
PathTest.GetBasePath()
方法定义在另一个项目中,例如:
namespace TestProject
public class PathTest
public static string GetBasePath()
return AppDomain.CurrentDomain.BaseDirectory;
为什么在 TestProject 程序集编译到 bin
文件夹时显示 ...\Web\
(换句话说,在我看来它应该显示 ...\Web\bin
)。
现在如果我将方法修改为:
namespace TestProject
public class FileReader
private const string m_filePath = @"\File.config";
public static string Read()
FileStream fs = null;
fs = new FileStream(AppDomain.CurrentDomain.BaseDirectory + m_filePath,FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(fs);
return reader.ReadToEnd();
File.config
是在 TestProject 中创建的。现在AppDomain.CurrentDomain.BaseDirectory + m_filePath
会返回..\Web\File.config
(实际上文件被复制到..\Web\bin\File.config
),会抛出异常。
您可以说我应该将m_filePath
修改为@"\bin\File.config"
。但是,如果我在您建议的控制台应用程序中使用此方法,AppDomain.CurrentDomain.BaseDirectory + m_filePath
将返回..\Console\bin\Debug\bin\File.config
(实际上文件已复制到.\Console\bin\Debug\File.config
),由于剩余bin
将引发异常。
换句话说,在网络应用程序中,AppDomain.CurrentDomain.BaseDirectory
是文件复制到的不同路径(缺少/bin
),但在控制台应用程序中它是相同的一个路径。
谁能帮帮我?
【问题讨论】:
Web 应用程序的基础是包含 ASPX 页面的 Web 根目录。 bin 文件夹只是根目录的子文件夹。 呸!我以为我疯了!我有同样的问题... 【参考方案1】:根据 MSDN,应用程序域“表示应用程序域,它是应用程序执行的隔离环境。”当您考虑 ASP.Net 应用程序时,应用程序所在的根目录不是 bin 文件夹。在您的 bin 文件夹中没有文件是完全可能的,并且在某些情况下是合理的,并且可能根本没有 bin 文件夹。由于 AppDomain.CurrentDomain 引用的是同一个对象,无论您是从后面的代码还是从 bin 文件夹中的 dll 调用代码,您最终都会得到网站的根路径。
当我编写设计为在 asp.net 和 windows 应用程序下运行的代码时,我通常会创建一个如下所示的属性:
public static string GetBasePath()
if(System.Web.HttpContext.Current == null) return AppDomain.CurrentDomain.BaseDirectory;
else return Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"bin");
另一个(未经测试的)选项是使用:
public static string GetBasePath()
return System.Reflection.Assembly.GetExecutingAssembly().Location;
【讨论】:
@kenny - 更新了一些信息System.Reflection.Assembly.GetExecutingAssembly().Location
在我的 Web 应用程序中指向:C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files...跨度>
我相信使用AppDomain.RelativeSearchPath
而不是硬编码“bin”会更正确。
字符串 basePath = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
检查HttpContext.Current
中的null
以确定您是否正在运行Web 应用程序是一个坏主意。例如,这在 async
上下文中不起作用。请改用RelativeSearchPath ?? BaseDirectory
。【参考方案2】:
如果您需要适用于 WinForms 和 Web 应用程序的解决方案
public string ApplicationPath
get
if (String.IsNullOrEmpty(AppDomain.CurrentDomain.RelativeSearchPath))
return AppDomain.CurrentDomain.BaseDirectory; //exe folder for WinForms, Consoles, Windows Services
else
return AppDomain.CurrentDomain.RelativeSearchPath; //bin folder for Web Apps
以上解决方案代码 sn-p 用于二进制位置
AppDomain.CurrentDomain.BaseDirectory
仍然是 Web 应用程序的有效路径,它只是 web.config
和 Global.asax
所在的根文件夹,与 Server.MapPath(@"~\");
相同
【讨论】:
【参考方案3】:如果你使用AppDomain.CurrentDomain.SetupInformation.PrivateBinPath
而不是BaseDirectory
,那么你应该得到正确的路径。
【讨论】:
注意,根据 MSDN,PrivatBinPath 可能是逗号分隔的文件夹字符串。 msdn.microsoft.com/en-us/library/… +1 这是迄今为止@Peter FWIW 在实践中的最佳答案,从我的观察来看似乎并非如此。不过,还没有准备好将其称为完整的文档错误 这将在控制台应用程序中返回 null。 不会给出真正的 exe 位置 @RobbVandaveer 是的,它可以返回 null,所以你应该使用PrivateBinPath ?? BaseDirectory
。【参考方案4】:
当 ASP.net 构建您的站点时,它会在其特殊位置为它们输出构建程序集。所以以这种方式获得路径很奇怪。
对于您可以使用的 asp.net 托管应用程序:
string path = HttpContext.Current.Server.MapPath("~/App_Data/somedata.xml");
【讨论】:
以上是关于为啥 AppDomain.CurrentDomain.BaseDirectory 在 asp.net 应用程序中不包含“bin”?的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 glTranslatef?为啥不直接更改渲染坐标?
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?