熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

ASP.NET用MasterPage代替PageBase技巧

2013-11-13 10:05:45  來源: .NET編程 

  目的
        實現用MasterPage中的cs文件 代替項目中的PageBase動機       
        寫這篇文章的動機來自於一次項目重構Net Framwork 的B/S架構項目中同時采用PageBase和MasterPage技術發現每次訪問頁面頁面同時訪問PageBase和MasterPage不僅造成性能降低甚至有可能給日後的項目功能擴充和調整帶來邏輯錯誤隱患技術環節

        PageBaseNet Framework 中經常使用的一種封裝多個頁面相同功能的技術PageBasecs類繼續自SystemWebUIPage類項目中的Web頁面繼續自PageBasecs類通過重寫基類中的頁面初始化方法實現調用PageBase中的業務功能例如url參數驗證保存訪問量等功能(具體實現方式參見微軟官方例子duwamishi)

        MasterPageNet Framework 中新特性物理上包括兩個文件分別是Master文件(Html標記)cs文件(C#代碼)Master文件實現顯示層繪制cs文件實現具體功能繼續自MasterPage的Web頁面可以繼續MasterPage中的顯示層內容繪制通用的頁頭頁腳定制統一的布局MasterPage是不錯的選擇模擬需求

       用MasterPage技術代替PageBase實現地址欄參數驗證
簡單的做個解釋吧      

  登錄系統之後url地址欄中帶有參數如下

此時用戶手動修改url地址欄中參數為

被視為非法操作系統將自動跳轉回登錄頁面
第一次代碼迭代
參照傳統PageBase方法
        傳統的Page做法為
public class PageBase : SystemWebUIPage
{   
    public PageBase()
    {
    }
    /**//// <summary>
    /// 入口方法
    /// </summary>
    protected void Initialize()
    {
        // 插入通用業務邏輯
     }
}
        Web頁面
public partial class TestPage : PageBase
{
    // 傳統的調用PageBase的方法    
    /**///// <summary>
    /// 重寫基類OnPreInit() 方法調用通用驗證方法
    /// </summary>
    /// <param name=e></param>
    protected override void OnInit(eventargs e)
    {
        baseInitialize();
    }
}
參照其做法將PageBase中的代碼移入MasterPage中
MasterPagecs
public partial class MyMasterPage : SystemWebUIMasterPage
{
    protected void Page_Load(object sender EventArgs e)
    {
        if (!IsPostBack)
        {

  // 調用驗證方法
            Initialize();
        }
    }
}
將Web頁面中的代碼修改為
public partial class TestPage : SystemWebUIPage
{   
    // 仿照PageBase方法調用Master中的方法 
    /**//// <summary>
    /// 重寫基類OnPreInit() 方法調用通用驗證方法
    /// </summary>
    /// <param name=e></param>
    protected override void OnInit(eventargs e)
    {       
        // 獲得母板頁引用
        MyMasterPage myMasterPage = (MyMasterPage)thisMaster;
        // 調用母板頁中通用驗證方法
        if (!IsPostBack)
        {
            myMasterPageInitialize();
        }
    }
}將MasterPage中的Initialize()方法替換為實例中的測試代碼
        步驟用 用戶名zhangsan登錄系統登錄成功
                      頁面顯示 歡迎 zhangsan 登錄
                      url地址顯示
                     
        步驟手動修改url地址欄如下
                     
        頁面不會顯示 歡迎lisi登錄而是跳轉回登錄頁面

  反思雖然功能實現但是存在不理想的環節
        Master中的被子類調用方法必須是public方法
        雖然不用修改Web頁的繼續但是依然要機械的復制粘貼重寫基類的OnInit()方法
為了消除這些懷味道於是開始
第二次代碼迭代
修改MasterPagecs中的代碼
public partial class MyMasterPage : SystemWebUIMasterPage
{
    protected void Page_Load(object sender EventArgs e)
    {
        if (!IsPostBack)
        {
            // 調用驗證方法

  CheckLogin();
        }
    }
    /**//// <summary>
    /// 驗證訪問是否合法
    /// </summary>
    private void CheckLogin()
    {     
        // 假如 url中的編號 或 cookie中的編號
        if (stringIsNullOrEmpty(RequestQueryString[id])
            stringIsNullOrEmpty(CookieUtilReadCookieByKey(id)))
        {
            ResponseRedirect(LoginASPx);
        }// 假如url中的編號 和 cookie中的編號 不匹配返回登錄頁       
        else if (intParse(RequestQueryString[id]) != intParse(CookieUtilReadCookieByKey(id)))
        {
            ResponseRedirect(Loginaspx);
        }     
    }
}重構之後Web頁可以不進行任何修改MasterPage在自身的Page_Load()方法中自動調用驗證方法而且將驗證方法設置為private僅供MasterPage自身調用提高安全性至此代碼似乎比較理想了測試
        步驟一用 用戶名 zhangsan登錄系統
                        依然顯示用戶登錄頁面
                        測試失敗
用斷點跟蹤代碼發現問題出現在MasterPagecs中的CheckLogin()方法中的代碼片段
if (stringIsNullOrEmpty(RequestQueryString[id])
            stringIsNullOrEmpty(CookieUtilReadCookieByKey(id)))
{
      ResponseRedirect(Loginaspx);
}
由於登錄頁繼續自MasterPage所以頁面加載時自動調用MasterPagecs中的驗證方法而自身的參數又不滿足stringIsNullOrEmpty()方法於是又跳回到登錄頁面登錄頁面在再次在加載時調用基類中的驗證方法於是形成死循環
在PageBase技術中Web頁面可以有選擇的繼續自PageBase而MasterPage技術中為了獲得一致的顯示層效果Web頁面對繼續MasterPage的選擇性是非常底的而且我們也不應該采用新建相同顯示不帶有驗證代碼的MasterPage來給不需要繼續基類功能的Web頁面來繼續這種方式顯然不合理為了解決這個問題於是開始了
第三次迭代
引入配置文件
<?XML version= encoding=utf ?>
<pages>
  <testpage>
    <page title=TestPage url=TestPageaspx needvalidate=true/>
    <page title=Login url=Loginaspx needvalidate=false/>

  </testpage>
  <adminpages>
    <page title=Page url=~/Admin/Pageaspx needvalidate=false/>
    <page title=Page url=~/Admin/Pageaspx needvalidate=false/>
  </adminpages>
</pages>
從中可以看到將需要驗證的頁面加以標識(needvalidate=true
創建Xml數據訪問類
public class XmlDAL
{
    private static string filePath = stringEmpty;
    static XmlDAL()
    {
        // 初始化配置文件路徑
        filePath = HttpContextCurrentRequestMapPath(~/App_Data/xml/ + Pagesxml);
    }
    /**//// <summary>
    /// 獲得需要驗證的頁面列表
    /// </summary>
    /// <returns>需要驗證的頁面列表</returns>
    public static IList<string> GetValidatePages()
    {
        IList<string> pages = new List<string>();
        // 假如指定配置文件存在
        if (SystemIOFileExists(filePath))
        {           
            try
            {               
                XmlDocument xmlDoc = new XmlDocument();                
                xmlDocLoad(filePath);
                // 獲取配置文件根節點
                XmlNode root = xmlDocDocumentElement;
                string XPath = /pages/testpage/page[@needvalidate=true];
                XmlNodeList nodeList = rootSelectNodes(xpath);
                // 便利節點集合
                foreach (XmlNode node in nodeList)
                {
                    pagesAdd(nodeAttributes[title]Value);

  }
            }
            catch (Exception ex)
            {
                throw new Exception(exMessage);
            }           
        }
        return pages;
    }
}
重構MasterPagecs中的代碼加入IsValidateNeeded(string url)方法用於檢測當前頁面是否需要驗證修改驗證方法
public partial class MyMasterPage : SystemWebUIMasterPage
{
    protected void Page_Load(object sender EventArgs e)
    {
        if (!IsPostBack)
        {
            // 調用驗證方法
            CheckLogin();
        }
    }
    /**//// <summary>
    /// 驗證訪問是否合法
    /// </summary>
    private void CheckLogin()
    {
        // 判定當前訪問頁面是否需要進行驗證
        if (IsValidateNeeded(RequestRawUrl))
        {
            // 假如 url中的編號 或 cookie中的編號
            if (stringIsNullOrEmpty(RequestQueryString[id])
                stringIsNullOrEmpty(CookieUtilReadCookieByKey(id)))
            {
                ResponseRedirect(Loginaspx);
            }// 假如url中的編號 和 cookie中的編號 不匹配返回登錄頁       
            else if (intParse(RequestQueryString[id]) != intParse(CookieUtilReadCookieByKey(id)))
            {
                ResponseRedirect(Loginaspx);
            }
        }
    }
    /**//// <summary>
    /// 驗證當前頁是否需要驗證

  /// </summary>
    /// <param name=currentPage>當前頁面名稱</param>
    /// <returns>是否需要驗證狀態</returns>
    private bool IsValidateNeeded(string url)
    {
        bool isNeeded = false;
        // GetValidatePages() 方法返回需要驗證頁面列表

  IList<string> pages = XmlDALGetValidatePages();
        IEnumerator<string> ie = pagesGetEnumerator();
        while (ieMoveNext())
        {
            // 假如當前頁面需要進行驗證
            if (urlContains(ieCurrent))
                // 返回需要驗證狀態
                return isNeeded = true;
        }
        return isNeeded;
    }
}
進行測試
        步驟用 用戶名zhangsan登錄系統登錄成功
                      頁面顯示 歡迎 zhangsan 登錄
                      url地址顯示
                     
        步驟手動修改url地址欄如下
                     
        頁面不會顯示 歡迎lisi登錄而是跳轉回登錄頁面至此我的代碼迭代結束了


From:http://tw.wingwit.com/Article/program/net/201311/12539.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.