【轉】擴展視圖功能

本文轉自:http://www.cnblogs.com/wheretime/p/3984170.html

在正式講解擴展視圖功能以前,我們有必要把視圖的工作原理簡單說明下。任何一個視圖都會被翻譯成一個c#類,並保存到指定的位置,然後被編譯。這也就是爲什麼能在視圖中包含c#代碼片段的原因。下面我們通過一個項目具體的瞭解一下這個過程,首先我們新建一個mvc3項目,它的Index.cshtml視圖文件的代碼如下:

@{
    ViewBag.Title = "主頁";
}
 
<h2>@ViewBag.Message</h2>
<p>
    若要了解有關 ASP.NET MVC 的更多信息,請訪問 <a href="http://asp.net/mvc" title="ASP.NET MVC 網站">http://asp.net/mvc</a>。
</p>

直到應用程序啓動之前,mvc應用程序的視圖不會被編譯,因此要查看此視圖翻譯成的類,需要啓動應用程序,並導航到一個動作方法。可以選擇任何動作方法,這是因爲,發送到mvc應用程序的最初請求會觸發視圖編譯過程。視圖所生成的類被保存在磁盤上,隨後被編譯。以win7爲例,文件保存位置爲C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files文件夾(其他版本的操作系統請自行對應)。這裏我把上面的這個視圖生成的c#類代碼帖出來:

#pragma checksum "C:\Users\Tony\Desktop\MvcApplication1\MvcApplication1\Views\Home\Index.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "AF52BBBCDF69BE7D53364ACEEB11ED8A27B4CDCE"
//------------------------------------------------------------------------------
// <auto-generated>
//     此代碼由工具生成。
//     運行時版本:4.0.30319.18063
//
//     對此文件的更改可能會導致不正確的行爲,並且如果
//     重新生成代碼,這些更改將會丟失。
// </auto-generated>
//------------------------------------------------------------------------------
 
namespace ASP {
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Helpers;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.WebPages;
    using System.Web.Mvc;
    using System.Web.Mvc.Ajax;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
     
     
    public class _Page_Views_Home_Index_cshtml : System.Web.Mvc.WebViewPage<dynamic> {
         
#line hidden
 
         
        public _Page_Views_Home_Index_cshtml() {
        }
         
        protected ASP.global_asax ApplicationInstance {
            get {
                return ((ASP.global_asax)(Context.ApplicationInstance));
            }
        }
         
        public override void Execute() {
 
             
            #line 1 "C:\Users\ZhangMeng\Desktop\MvcApplication1\MvcApplication1\Views\Home\Index.cshtml"
   
    ViewBag.Title = "主頁";
 
 
             
            #line default
            #line hidden
WriteLiteral("\r\n<h2>");
 
 
             
            #line 5 "C:\Users\ZhangMeng\Desktop\MvcApplication1\MvcApplication1\Views\Home\Index.cshtml"
Write(ViewBag.Message);
 
             
            #line default
            #line hidden
WriteLiteral("</h2>\r\n<p>\r\n    若要了解有關 ASP.NET MVC 的更多信息,請訪問 <a href=\"http://asp.net/mvc\" title=\"" +
"ASP.NET MVC 網站\">http://asp.net/mvc</a>。\r\n</p>\r\n");
 
 
        }
    }
}

關於這個文件有以下幾點給大家說明下:

  1. 類名格式:生成的類名稱格式爲"_Page_Views_控制器名_視圖名_文件擴展名"。大家可以看到生成的類名爲"_Page_Views_Home_Index_cshtml"符合這個格式。
  2. 父類:如果視圖不是強類型視圖則此類繼承自System.Web.Mvc.WebViewPage<dynamic>,如果視圖爲強類型視圖則繼承自System.Web.Mvc.WebViewPage<指定的模型類>。
  3. 輸出:通過調用此類的Execute方法輸出視圖內容。

  至此關於視圖的工作原理大家應該有一定的瞭解了(大家有時間可以多研究一下這個類,對提高mvc水平還是很有幫助的),接下來進入今天的正題:擴展視圖功能。通過上面講解視圖的工作原理大家可以看出,要想擴展視圖的功能,一個非常好的切入點就是擴展視圖基類。我們以多店版網上商城BrnMall爲例,代碼如下:

using System;
 
namespace BrnMall.Web.Framework
{
    /// <summary>
    /// 商城前臺視圖頁面基類型
    /// </summary>
    public abstract class WebViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
    {
        public WebWorkContext WorkContext;
 
        public override void InitHelpers()
        {
            base.InitHelpers();
            WorkContext = ((BaseWebController)(this.ViewContext.Controller)).WorkContext;
        }
    }
 
    /// <summary>
    /// 商城前臺視圖頁面基類型
    /// </summary>
    public abstract class WebViewPage : WebViewPage<dynamic>
    {
    }
}

在此類中我們添加了一個屬性WorkContext,並在InitHelpers方法中對它進行賦值。這樣我們在視圖中就可以直接訪問這個屬性而不需要每次都通過控制器進行類型轉換獲得。代碼如下:

@foreach (NavInfo info in WorkContext.NavList)
{
<li><a href="@info.Url">@info.Name</a></li>
}

不過要想讓此視圖基類正常工作還需要對視圖文件夾中的Web.config文件中進行修改,代碼如下:

<system.web.webPages.razor>
  <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
  <!--將pageBaseType的默認值替換爲WebViewPage類型-->
  <pages pageBaseType="BrnMall.Web.Framework.WebViewPage">
    <namespaces>
      <add namespace="System.Web.Mvc" />
      <add namespace="System.Web.Mvc.Ajax" />
      <add namespace="System.Web.Mvc.Html" />
      <add namespace="System.Web.Routing" />
      <add namespace="System.Text" />
      <add namespace="System.Data" />
      <add namespace="System.Collections"/>
      <add namespace="System.Collections.Generic"/>
      <add namespace="BrnMall.Core" />
      <add namespace="BrnMall.Services" />
      <add namespace="BrnMall.Web.Framework" />
      <add namespace="BrnMall.Web.Models" />
    </namespaces>
  </pages>
</system.web.webPages.razor>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章