为啥 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.configGlobal.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,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?