web-dev-qa-db-ja.com

AppDomain.CurrentDomain.BaseDirectoryにasp.netアプリに「bin」が含まれないのはなぜですか?

次のようなWebプロジェクトがあります。

_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

つまり、Webアプリでは、_AppDomain.CurrentDomain.BaseDirectory_はファイルのコピー先となる別のパス(_/bin_の欠如)ですが、コンソールアプリでは同じ1つのパスです。
誰か助けていただけますか?

25
Domi.Zhang

MSDNによると、アプリドメインは「アプリケーションドメインを表します。これは、アプリケーションが実行される分離された環境です。」 ASP.Netアプリケーションについて考えるとき、アプリケーションが存在するルートはbinフォルダーではありません。 binフォルダーにファイルがなく、場合によってはbinフォルダーがまったくないことは完全に可能であり、場合によっては合理的です。 AppDomain.CurrentDomainは、コードビハインドからコードを呼び出すか、binフォルダー内のdllからコードを呼び出すかに関係なく、同じオブジェクトを参照するため、Webサイトへのルートパスになります。

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;
} 
35
Peter

WinFormsおよびWeb Appsで機能するソリューションが必要な場合

_    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 
            }
        }
    }
_

上記のソリューションコードスニペットはバイナリの場所用です

_AppDomain.CurrentDomain.BaseDirectory_は引き続きWebアプリの有効なパスであり、_web.config_と_Global.asax_がルートフォルダーであり、Server.MapPath(@"~\");と同じです。

19
Pawel Cioch

BaseDirectoryの代わりにAppDomain.CurrentDomain.SetupInformation.PrivateBinPathを使用する場合、正しいパスを取得する必要があります。

15
M4N

ASP.netがサイトをビルドすると、ビルドアセンブリが特別な場所に出力されます。したがって、そのようにパスを取得するのは奇妙です。

Asp.netホストアプリケーションの場合、次を使用できます。

string path = HttpContext.Current.Server.MapPath("~/App_Data/somedata.xml");
2
Siarhei Kuchuk