2012-04-13 40 views
0

我想讀一個視圖的內容爲一個字符串變量,像這樣 -如何從業務層裝配中獲取視圖的路徑?

string _template = File.ReadAllText(@"Views/emails/registrationconfirmation.cshtml");

這所以可以用RazorEngine用於從模板創建的電子郵件。

此代碼位於我的業務層組件中。我想我需要物理路徑而不是我想要使用的虛擬路徑。

該文件位於我的MVC3項目的Views/emails文件夾中。如何以編程方式獲取我需要讀取文件的正確路徑?

+0

你評價過ActionMailer.NET嗎?值得一看,可以通過NuGet安裝。 https://bitbucket.org/swaj/actionmailer.net/wiki/Home – 2012-04-13 01:56:03

+0

謝謝,我打算看看這個獨立版本。實際上我也讀過它使用RazorEngine,這很有趣。感謝您的鏈接! – 2012-04-13 23:41:02

回答

1

您的業務層不應試圖獲取視圖的路徑。如果它需要使用這樣的路徑,它們應該作爲UI層的參數傳遞。的

因此,在業務層而不是這樣的:

public class MyBusiness : IMyBusiness 
{ 
    public string RenderView() 
    { 
     string _template = File.ReadAllText(@"Views/emails/registrationconfirmation.cshtml"); 
     ... 
    } 
} 

你可以有這樣的:

public class MyBusiness 
{ 
    public string RenderView(string viewPath) 
    { 
     string _template = File.ReadAllText(viewPath); 
     ... 
    } 
} 

它現在位於您的控制器會照顧調用代碼的責任傳遞正確的路徑(在ASP.NET應用程序的情況下,可以使用Server.MapPath函數獲得,而在桌面應用程序的情況下可以是相對路徑等)。這樣您的業務層就不再與ASP.NET緊密結合了。

另一種可能性是具有業務層把你的應用程序的基本物理路徑的構造函數參數:

public class MyBusiness : IMyBusiness 
{ 
    private readonly string _basePath; 
    public MyBusiness(string basePath) 
    { 
     _basePath = basePath; 
    } 

    public string RenderView() 
    { 
     var file = Path.Combine(_basePath, @"Views\emails\registrationconfirmation.cshtml"); 
     string _template = File.ReadAllText(viewPath); 
     ... 
    } 
} 

,然後所有剩下的是配置DI框架傳遞HostingEnvironment.ApplicationPhysicalPath屬性值實例化時您的業​​務層。


更新:由於@jgauffin在評論部分中指出該代碼可以通過傳遞StreamStreamReader到業務層可以進一步改進,使之甚至不依賴於文件。這將使它更容易重用和單元測試完全隔離。

+0

我寧願將'Stream'傳遞給業務層。 – jgauffin 2012-04-13 06:28:49

+0

@jgauffin,是一個'Stream',真是個好主意。這樣業務層代碼甚至不依賴於文件,並且可以很容易地單獨進行單元測試。我會更新我的文章以考慮到這一點。 – 2012-04-13 06:31:39

+0

@Darin,感謝你的這兩種技術。一個問題,如果我要傳遞一個'Stream',那麼實際上只是傳遞一個引用或整個流被複制?謝謝, – 2012-04-13 23:26:26

0

請問Server.MapPath適合您的情況嗎?

+0

我不這麼認爲。 「服務器」對象似乎在業務層組件中不可用。我認爲它不適用於MVC應用程序組件之外。不過謝謝。 – 2012-04-13 23:22:12