Почему AppDomain.CurrentDomain.BaseDirectory не содержит "bin" в приложении asp.net?

У меня есть веб-проект вроде:

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

Почему он отображает ...\Web\, в то время как сборка TestProject скомпилирована в папку bin (другими словами, она должна отображать ...\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();
        }
    }
}

В TestProject создается File.config. Теперь AppDomain.CurrentDomain.BaseDirectory + m_filePath будет returen ..\Web\File.config (на самом деле файл был скопирован в ..\Web\bin\File.config), будет выбрано исключение.

Можно сказать, что я должен изменить m_filePath на @"\bin\File.config". Однако, если я использую этот метод в приложении Console в вашем предложить, AppDomain.CurrentDomain.BaseDirectory + m_filePath вернет ..\Console\bin\Debug\bin\File.config (на самом деле файл был скопирован в .\Console\bin\Debug\File.config), исключение будет выбрано из-за избытка bin.

Другими словами, в веб-приложении AppDomain.CurrentDomain.BaseDirectory - это другой путь, в который файл копируется (отсутствует /bin), но в консольном приложении это один и тот же путь.
Кто-нибудь может мне помочь?

Ответ 1

В MSDN домен приложения "Представляет домен приложения, который является изолированной средой, где выполняются приложения". Когда вы думаете о приложении ASP.Net, корневой каталог, в котором находится приложение, не является папкой bin. Вполне возможно, и в некоторых случаях разумно, чтобы у вас не было файлов в папке bin и, возможно, нет папки bin. Поскольку AppDomain.CurrentDomain относится к одному и тому же объекту, независимо от того, вызываете ли вы код из кода позади или из библиотеки dll в папке bin, в конечном итоге вы получите корневой путь к веб-сайту.

Когда я написал код, предназначенный для работы в обоих приложениях 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;
} 

Ответ 2

Если вы используете AppDomain.CurrentDomain.SetupInformation.PrivateBinPath вместо BaseDirectory, то вы должны получить правильный путь.

Ответ 3

Если вам нужно решение, которое работает для WinForms и веб-приложений

    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.config и Global.asax и такая же, как Server.MapPath(@"~\");

Ответ 4

Когда ASP.net создает ваш сайт, он выводит сборки сборки в свое особое место для них. Так что путь таким образом странный.

Для приложений, размещенных в asp.net, вы можете использовать:

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