ASP.NET MVC的View是如何呈現出來的[執行個體篇]

來源:互聯網
上載者:User

在《[設計篇]》篇中我們通過對View引擎的總體介紹講述了從ViewResult的建立到View呈現的原理,為了讓讀者對View引擎及其View呈現機制具有一個深刻的認識,我們自訂一個簡單的用於呈現靜態HTML的StaticFileViewEngine。在一個通過Visual Studio的ASP.NET MVC項目模板建立的空Web應用中,我們定義了如下一個針對於靜態HTML內容呈現的自訂StaticFileView。StaticFileView實現了IView介面,在實現的Render方法中讀取制定檔案的內容寫入作為參數的TextWriter。

   1: public class StaticFileView:IView
2: {
3: public string FileName { get; private set; }
4: public StaticFileView(string fileName)
5: {
6: this.FileName = fileName;
7: }
8: public void Render(ViewContext viewContext, TextWriter writer)
9: {
10: byte[] buffer;
11: using (FileStream fs = new FileStream(this.FileName, FileMode.Open))
12: {
13: buffer = new byte[fs.Length];
14: fs.Read(buffer, 0, buffer.Length);
15: }
16: writer.Write(Encoding.UTF8.GetString(buffer));
17: }
18: }

由於StaticFileView中定義的內容完全是靜態,所以緩衝顯得很有必要。我們只需要基於Controller和View名稱對View實施緩衝,為此我們定義了如下一個作為Key的資料類型ViewEngineResultCacheKey。

   1: internal class ViewEngineResultCacheKey
2: {
3: public string ControllerName { get; private set; }
4: public string ViewName { get; private set; }
5:
6: public ViewEngineResultCacheKey(string controllerName, string viewName)
7: {
8: this.ControllerName = controllerName ?? string.Empty;
9: this.ViewName = viewName ?? string.Empty;
10: }
11: public override int GetHashCode()
12: {
13: return this.ControllerName.ToLower().GetHashCode() ^ this.ViewName.ToLower().GetHashCode();
14: }
15:
16: public override bool Equals(object obj)
17: {
18: ViewEngineResultCacheKey key = obj as ViewEngineResultCacheKey;
19: if (null == key)
20: {
21: return false;
22: }
23: return key.GetHashCode() == this.GetHashCode();
24: }
25: }

具有如下定義的StaticFileViewEngine代表StaticFileView對應的ViewEngine。我們通過一個字典類型的欄位viewEngineResults作為對ViewEngineResult的緩衝,而View的擷取操作最終實現在InternalFindView方法中。通過StaticFileView表示的View定義在一個以View名稱作為檔案名稱的文字檔中,該檔案的副檔名為.shtml(Static HTML)。

   1: public class StaticFileViewEngine : IViewEngine
2: {
3: private Dictionary<ViewEngineResultCacheKey, ViewEngineResult> viewEngineResults = new Dictionary<ViewEngineResultCacheKey, ViewEngineResult>();
4: private object syncHelper = new object();
5: public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
6: {
7: return this.FindView(controllerContext, partialViewName, null, useCache);
8: }
9:
10: public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
11: {
12: string controllerName = controllerContext.RouteData.GetRequiredString("controller");
13: ViewEngineResultCacheKey key = new ViewEngineResultCacheKey(controllerName, viewName);
14: ViewEngineResult result;
15: if (!useCache)
16: {
17: result = InternalFindView(controllerContext, viewName, controllerName);
18: viewEngineResults[key] = result;
19: return result;
20: }
21: if(viewEngineResults.TryGetValue(key, out result))
22: {
23: return result;
24: }
25: lock (syncHelper)
26: {
27: if (viewEngineResults.TryGetValue(key, out result))
28: {
29: return result;
30: }
31:
32: result = InternalFindView(controllerContext, viewName, controllerName);
33: viewEngineResults[key] = result;
34: return result;
35: }
36: }
37:
38: private ViewEngineResult InternalFindView(ControllerContext controllerContext, string viewName, string controllerName)
39: {
40: string[] searchLocations = new string[]
41: {
42: string.Format( "~/views/{0}/{1}.shtml", controllerName, viewName),
43: string.Format( "~/views/Shared/{0}.shtml", viewName)
44: };
45:
46: string fileName = controllerContext.HttpContext.Request.MapPath(searchLocations[0]);
47: if (File.Exists(fileName))
48: {
49: return new ViewEngineResult(new StaticFileView(fileName), this);
50: }
51: fileName = string.Format(@"\views\Shared\{0}.shtml", viewName);
52: if (File.Exists(fileName))
53: {
54: return new ViewEngineResult(new StaticFileView(fileName), this);
55: }
56: return new ViewEngineResult(searchLocations);
57: }
58:
59: public void ReleaseView(ControllerContext controllerContext, IView view)
60: { }
61: }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.