2015-01-11 19 views
0

這是一個相當惱人的問題,我無法在堆棧和谷歌搜索後進行數十次搜索。在asp.net web應用程序中獲取要讀取的文本文件的完整路徑

我有一個Asp.Net web應用程序,該解決方案本身有7個項目,其中之一是一個MVC項目,其中類如下所示的駐留。

using System; 
using System.Web.Hosting; 
namespace MyApp.Notifications 
{ 
    public class CustomEmails 
    { 
     private readonly string basePath = "C:\\Users\\MyUser\\MyAppName\\"; 
     //HostingEnvironment.MapPath("~\\MyAppName") 
     //Server.MapPath("~") 
     //HostingEnvironment.ApplicationPhysicalPath("~"); 
     //HostingEnvironment.ApplicationVirtualPath; 

     var subject = File.ReadAllText(basePath + "Notifications\\EmailTemplates\\EmailConfirmationEvent_Subject.txt"); 
    //rest of classes code here 
    } 
} 

我可以讀取子文件夾中的文本文件的唯一方法是硬編碼路徑,如上所示。正如你上面看到的,我試圖以編程方式檢索應用程序的基本路徑,然後將其前置到文件子路徑。

正如你在上面看到的,在註釋掉的片段中,我嘗試了很多東西。

對於初學者來說,Server.MapPath永遠不會被允許,因爲它始終處於紅色狀態,intellisense不提供任何補救措施,並且使用Google搜索無法幫助其他人提供該Server.MapPath是IIS方法。所有其他代碼片段都不會返回任何內容。

我在做什麼錯?錯誤在哪裏?是不是有一種標準的方式來完成這個任務,因此無論您是在開發機器還是在主機虛擬機上,您總能獲得正確的基本路徑?

Per Darin的建議代碼更新如下;

public class EmailEvents 
{ 
    private static readonly string basePath = CustomEmails.GetWebsiteRoot(); 
    public class EmailAddressVerified : IEventHandler<EmailVerifiedEvent<UserAccount>> 
    { 
     public void Handle(EmailVerifiedEvent<UserAccount> evt) 
     { 
      dynamic smtp = new SmtpMessageDelivery(); 
      var localAppPath = CustomEmails.GetWebsiteRoot(); 
      var htmlBody = CustomEmails.GetHtmlEmailMessage(DomainClasses.Enums.EmailType.AccountConfirmation); 
      //{ProductionChange} --change the first parameter to false in production 
      htmlBody = CustomEmails.FillEmailPlaceholderText(false, htmlBody, evt.Account); 
      htmlBody = htmlBody.Replace(CustomEmails.EmailTextPlaceholders.HtmlFileKey, EncryptDecrypt.EncryptQueryString(Guid.NewGuid().ToString()));    
      var subject = File.ReadAllText(Path.Combine(basePath, "Notifications", "EmailTemplates", "EmailConfirmationEvent_Subject.txt")); 
      subject = subject.Replace(CustomEmails.EmailTextPlaceholders.ApplicationName, CustomEmails.EmailPlaceholderValues.ApplicationName); 

      var msg = new Message { To = evt.Account.Email, Subject = subject, Body = htmlBody }; 
      smtp.Send(msg); 
     } 
    } 
} 

在上面的示例中,basePath始終是空白,但localAppPath檢索正確的路徑。爲什麼類級別的專用變量不能檢索路徑?

+0

確保您的項目引用了'System.Web'庫。之後,intellisense應該建議'使用System.Web.Hosting'爲你 –

+0

我有,並仍然所有那些HostingEnvironment嘗試返回什麼 – dinotom

+0

'HostingEnvironment.MapPath(「〜/」);''會給你網站根的絕對路徑。當然,這隻能在ASP.NET Web主機上運行。如果您嘗試在ASP.NET環境(例如單元測試)之外執行此代碼,則它顯然不會返回任何內容。 –

回答

0

你可以聲明一個變量,然後你可以在運行時填充一個變量,只有一個get使它成爲只讀,然後在一個屬性中使用Server.MapPath。在編譯時你不能像在類聲明中那樣做,因爲它無法計算出字符串const是什麼,因爲Server.MapPath不能解析成它可以使用的const,因爲它幾乎肯定會隨着部署而改變。

public class CustomEmails 
{ 
    private string _basePath = null; 

    private string BasePath 
    { 
     get 
     { 
      if (_basePath == null) 
      { 
       this._basePath = Server.MapPath('...'); 
      } 
      return _basePath; 
     } 
    } 

在運行時您到this.BasePath第一個請求將填充使用的MapPath(一次調用),然後將所有後續調用該方法將使用先前獲得的值的私有變量。

+0

'Server'是WebForms基類的一個屬性。你的代碼永遠不會編譯,因爲'CustomEmails'不是從任何基類派生的。您應該使用'HostingEnvironment.MapMath',而不是靜態方法。 –

+0

@CodeUniqueely VS仍然不喜歡這一行中的服務器this._basePath = Server.MapPath('...');因爲它是紅色的,因爲它總是當我嘗試使用它 – dinotom

+0

@Darin您是否指的是程序集引用?因爲我沒有找到任何具有該名稱的文件 – dinotom

0

您可以使用HostingEnvironment.MapPath靜態方法。

  1. 添加參考System.Web裝配
  2. 添加using System.Web.Hosting
  3. 寫一類具有一個方法指的是網站根:

    using System.Web.Hosting; 
    
    namespace MyApp.Notifications 
    { 
        public class CustomEmails 
        { 
         public static string GetWebsiteRoot() 
         { 
          // Get the website root 
          return HostingEnvironment.MapPath("~/"); 
         } 
        } 
    } 
    

備註:本HostingEnvironment.MapPath將工作只在ASP.NET Webhost內部。如果您嘗試在外部使用它(例如單元測試或桌面應用程序),它將不會返回所需的結果。

在這種情況下,將您的函數視爲依賴於網站根路徑要好得多。這將使他們更容易進行單元測試。它只在Composition Root內部,您將使用正確的方法注入路徑。對於將作爲HostingEnvironment.MapPath方法的ASP.NET Web上下文。

另外,當你在處理目錄路徑時,你完全希望使用Path.Combine方法,而不是你在問題中使用的+運算符。例如:

string root = CustomEmails.GetWebsiteRoot(); 
string path = Path.Combine(root, "Notifications", "EmailTemplates", "EmailConfirmationEvent_Subject.txt"); 
+0

謝謝,我正在吃晚餐。當我可以測試它 – dinotom

+0

嗯,我測試了它,var basepath = GetWebsiteRoot,使用你的代碼仍然沒有返回,現在我正在吃晚餐。 – dinotom

+0

好的,現在我已經測試了幾種不同的方法。當在帖子中使用時,它會給出一個沒有任何值的值; - private readonly string basePath = GetWebsiteRoot();如果我在需要的方法中添加一個變量,它確實會產生正確的路徑。爲什麼這不是作爲私有類級變量工作,而是在方法中作爲局部變量工作?我更喜歡它作爲課程級別,因爲我在許多方法中使用它。 – dinotom

相關問題