2011-12-29 27 views
20

tôi có một dự án web như:Tại sao AppDomain.CurrentDomain.BaseDirectory không chứa "bin" trong ứng dụng asp.net?

namespace Web 
{ 
    public partial class _Default : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
      lbResult.Text = PathTest.GetBasePath(); 
     } 
    } 
} 

Phương pháp PathTest.GetBasePath() được định nghĩa trong dự án khác như:

namespace TestProject 
{ 
    public class PathTest 
    { 
     public static string GetBasePath() 
     { 
      return AppDomain.CurrentDomain.BaseDirectory; 
     } 
    } 
} 

Tại sao nó hiển thị ...\Web\ trong khi lắp ráp TestProject được biên dịch vào bin thư mục (hay nói cách khác nó sẽ hiển thị ...\Web\bin trong suy nghĩ của tôi).

Bây giờ tôi có một rắc rối nếu tôi sửa đổi phương pháp thành:

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

Các File.config được tạo ra trong TestProject. Bây giờ AppDomain.CurrentDomain.BaseDirectory + m_filePath sẽ trả lại ..\Web\File.config (thực sự tệp được sao chép vào ..\Web\bin\File.config), một ngoại lệ sẽ được ném.

Bạn có thể nói rằng tôi nên sửa đổi m_filePath thành @"\bin\File.config". Tuy nhiên, nếu tôi sử dụng phương pháp này trong ứng dụng Console trong đề xuất của bạn, AppDomain.CurrentDomain.BaseDirectory + m_filePath sẽ trả lại ..\Console\bin\Debug\bin\File.config (thực sự tệp được sao chép thành .\Console\bin\Debug\File.config), một ngoại lệ sẽ được ném do số dư bin.

Nói cách khác, trong ứng dụng web, AppDomain.CurrentDomain.BaseDirectory là một đường dẫn khác mà tệp được sao chép vào (thiếu /bin), nhưng trong ứng dụng bảng điều khiển, đó là cùng một đường dẫn.
Bất kỳ ai có thể giúp tôi?

+0

Cơ sở của ứng dụng web là gốc web nơi chứa các trang ASPX. Thư mục bin chỉ là thư mục con của thư mục gốc. – Tejs

+0

Phew! Tôi nghĩ rằng tôi đã phát điên! Tôi đã gặp vấn đề tương tự ... – ECC

Trả lời

28

Mỗi MSDN, một miền ứng dụng "Đại diện cho miền ứng dụng, là môi trường riêng biệt nơi ứng dụng thực thi". Khi bạn nghĩ về một ứng dụng ASP.Net gốc, nơi ứng dụng cư trú không phải là thư mục bin. Nó là hoàn toàn có thể, và trong một số trường hợp hợp lý, không có tập tin trong thư mục bin của bạn, và có thể không có thư mục bin nào cả. Kể từ khi AppDomain.CurrentDomain đề cập đến cùng một đối tượng bất kể bạn gọi mã từ mã phía sau hoặc từ một dll trong thư mục bin bạn sẽ kết thúc với đường dẫn gốc đến trang web.

Khi tôi đã viết mã được thiết kế để chạy theo cả asp.net và cửa sổ thường apps tôi tạo ra một tài sản đó trông giống như sau:

public static string GetBasePath()   
{  
    if(System.Web.HttpContext.Current == null) return AppDomain.CurrentDomain.BaseDirectory; 
    else return Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"bin"); 
} 

khác (chưa được kiểm tra) tùy chọn sẽ được sử dụng:

public static string GetBasePath()   
{  
    return System.Reflection.Assembly.GetExecutingAssembly().Location; 
} 
+0

một cách giải quyết tốt đẹp, nhưng nó không trả lời tại sao .... có lẽ không có câu trả lời hay. – kenny

+0

@kenny - Cập nhật với một chút thông tin – Peter

+1

Câu trả lời của bạn rất rõ ràng và hữu ích, cảm ơn rất nhiều! –

14

Nếu bạn sử dụng AppDomain.CurrentDomain.SetupInformation.PrivateBinPath thay vì BaseDirectory, thì bạn sẽ nhận được đường dẫn chính xác.

+1

Lưu ý, theo MSDN PrivatBinPath có thể là một chuỗi phân cách bằng dấu phẩy. http://msdn.microsoft.com/en-us/library/system.appdomainsetup.privatebinpath.aspx – Peter

+0

+1 Đây là câu trả lời hay nhất @Peter FWIW trong thực tế nó dường như không phải từ quan sát của tôi. Chưa sẵn sàng để gọi nó là một lỗi doc đầy đủ mặc dù –

+0

làm việc tuyệt vời nhờ – Neo

2

Khi ASP.net xây dựng trang web của bạn, đầu ra sẽ xây dựng các cụm ở vị trí đặc biệt cho chúng. Vì vậy, nhận được con đường theo cách đó là lạ.

Đối với asp.net tổ chức ứng dụng mà bạn có thể sử dụng:

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

Trong trường hợp bạn muốn có một giải pháp mà làm việc cho WinForms và 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 
      } 
     } 
    } 

Trên đoạn mã giải pháp là cho những chương trình địa điểm

Các AppDomain.CurrentDomain.BaseDirectory vẫn là đường dẫn hợp lệ cho Ứng dụng web, nó chỉ là một thư mục gốc nơi web.configGlobal.asax và giống như Server.MapPath(@"~\");

Các vấn đề liên quan