用MasterPage 代替 PageBase

2016-02-19 20:57 33 1 收藏

想不想get新技能酷炫一下,今天图老师小编就跟大家分享个简单的用MasterPage 代替 PageBase教程,一起来看看吧!超容易上手~

【 tulaoshi.com - Web开发 】

  目的:
          实现用MasterPage中的.cs文件 代替项目中的PageBase。

  动机:       
          写这篇文章的动机,来自于一次项目重构。在.Net Framwork 2.0的B/S架构项目中同时采用PageBase和MasterPage技术,发现每次访问页面,页面同时访问PageBase和MasterPage,不仅造成性能降低,甚至有可能给日后的项目功能扩充和调整带来逻辑错误隐患。

  技术环节:
          PageBase:.Net Framework 1.1 中经常使用的一种封装多个页面相同功能的技术。PageBase.cs类继承自System.Web.UI.Page类,项目中的Web页面继承自PageBase.cs类,通过重写基类中的页面初始化方法,实现调用PageBase中的业务功能,例如:url参数验证,保存访问量等功能(具体实现方式参见微软官方例子duwamishi)。
          MasterPage:.Net Framework 2.0 中新特性,物理上包括两个文件,分别是:.Master文件(html标记),.cs文件(C#代码)。.Master文件实现显示层绘制,.cs文件实现具体功能。继承自MasterPage的Web页面可以继承MasterPage中的显示层内容。绘制通用的页头页脚,定制统一的布局,MasterPage是不错的选择。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

  模拟需求:
         用MasterPage技术,代替PageBase,实现地址栏参数验证。
  简单的做个解释吧,数据库中Login表信息如下图:            
  
  登录系统之后,url地址栏中带有参数,如下:
  http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
  此时用户手动修改url地址栏中参数为:
  http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
  被视为非法操作,系统将自动跳转回登录页面。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

  
  第一次代码迭代:

  
  1.参照传统PageBase方法:
          传统的Page做法为:
  public class PageBase : System.Web.UI.Page
  {   
      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)
      {
          base.Initialize();
      }
  }
  参照其做法,将PageBase中的代码移入MasterPage中:
  MasterPage.cs:
  public partial class MyMasterPage : System.Web.UI.MasterPage
  {
      protected void Page_Load(object sender, EventArgs e)
      {
          if (!IsPostBack)
          {
              // 调用验证方法
              Initialize();
          }
      }
  }
  将Web页面中的代码修改为:
  public partial class TestPage : System.Web.UI.Page
  {   
      // 仿照PageBase方法,调用Master中的方法 
      /**//// summary
      /// 重写基类OnPreInit() 方法,调用通用验证方法
      /// /summary
      /// param name="e"/param
      protected override void OnInit(eventargs e)
      {       
          // 获得母板页引用
          MyMasterPage myMasterPage = (MyMasterPage)this.Master;
          // 调用母板页中通用验证方法
          if (!IsPostBack)
          {
              myMasterPage.Initialize();
          }
      }
  }将MasterPage中的Initialize()方法替换为实例中的,测试代码:
          步骤1:用 用户名zhangsan登录系统,登录成功,
                        页面显示 欢迎 zhangsan 登录。
                        url地址显示:
                        http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
          步骤2:手动修改url地址栏:如下:
                        http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
          页面不会显示 欢迎lisi登录,而是跳转回登录页面。
  反思:虽然功能实现,但是存在不理想的环节:
          1. Master中的被子类调用方法必须是public方法;
          2. 虽然不用修改Web页的继承,但是依然要机械的复制粘贴重写基类的OnInit()方法。
  为了消除这些怀味道,于是开始:
  第二次代码迭代:
  修改MasterPage.cs中的代码:
  public partial class MyMasterPage : System.Web.UI.MasterPage
  {
      protected void Page_Load(object sender, EventArgs e)
      {
          if (!IsPostBack)
          {
              // 调用验证方法
              CheckLogin();
          }
      }
      /**//// summary
      /// 验证访问是否合法
      /// /summary
      private void CheckLogin()
      {     
          // 如果 url中的编号 或 cookie中的编号
          if (string.IsNullOrEmpty(Request.QueryString["id"])
              || string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
          {
              Response.Redirect("Login.aspx");
          }// 如果url中的编号 和 cookie中的编号 不匹配,返回登录页       
          else if (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
          {
              Response.Redirect("Login.aspx");
          }     
      }
  }重构之后,Web页可以不进行任何修改,MasterPage在自身的Page_Load()方法中自动调用验证方法,而且将验证方法设置为private,仅供MasterPage自身调用,提高安全性。至此,代码似乎比较理想了,测试:
          步骤一:用 用户名 zhangsan登录系统,
                          依然显示用户登录页面。
                          测试失败。
  用断点跟踪代码,发现问题出现在MasterPage.cs中的CheckLogin()方法中的代码片段:
  if (string.IsNullOrEmpty(Request.QueryString["id"])
              || string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
  {
        Response.Redirect("Login.aspx");
  }
  由于登录页继承自MasterPage,所以页面加载时自动调用MasterPage.cs中的验证方法,而自身的参数又不满足string.IsNullOrEmpty()方法,于是又跳回到登录页面,登录页面在再次在加载时调用基类中的验证方法,于是形成死循环。
  在PageBase技术中,Web页面可以有选择的继承自PageBase,而MasterPage技术中,为了获得一致的显示层效果,Web页面对继承MasterPage的选择性是非常底的,而且我们也不应该采用新建相同显示,不带有验证代码的MasterPage,来给不需要继承基类功能的Web页面来继承,这种方式显然不合理。为了解决这个问题,于是开始了
  第三次迭代:
  引入配置文件:
  ?xml version="1.0" encoding="utf-8" ?
  pages
    testpage
      page title="TestPage" url="TestPage.aspx" needvalidate="true"/
      page title="Login" url="Login.aspx" needvalidate="false"/
    /testpage
    adminpages
      page title="Page1" url="~/Admin/Page1.aspx" needvalidate="false"/
      page title="Page2" url="~/Admin/Page2.aspx" needvalidate="false"/
    /adminpages
  /pages
  从中可以看到,将需要验证的页面加以标识(needvalidate="true")。
  创建Xml数据访问类:
  public class XmlDAL
  {
      private static string filePath = string.Empty;
      static XmlDAL()
      {
          // 初始化配置文件路径
          filePath = HttpContext.Current.Request.MapPath("~/App_Data/xml/" + "Pages.xml");
      }
      /**//// summary
      /// 获得需要验证的页面列表
      /// /summary
      /// returns需要验证的页面列表/returns
      public static IListstring GetValidatePages()
      {
          IListstring pages = new Liststring();
          // 如果指定配置文件存在
          if (System.IO.File.Exists(filePath))
          {           
              try
              {               
                  XmlDocument xmlDoc = new XmlDocument();                
                  xmlDoc.Load(filePath);
                  // 获取配置文件根节点
                  XmlNode root = xmlDoc.DocumentElement;
                  string xpath = "/pages/testpage/page[@needvalidate='true']";
                  XmlNodeList nodeList = root.SelectNodes(xpath);
                  // 便利节点集合
                  foreach (XmlNode node in nodeList)
                  {
                      pages.Add(node.Attributes["title"].Value);
                  }
              }
              catch (Exception ex)
              {
                  throw new Exception(ex.Message);
              }           
          }
          return pages;
      }
  }
  重构MasterPage.cs中的代码,加入IsValidateNeeded(string url)方法,用于检测当前页面是否需要验证,修改验证方法:
  public partial class MyMasterPage : System.Web.UI.MasterPage
  {
      protected void Page_Load(object sender, EventArgs e)
      {
          if (!IsPostBack)
          {
              // 调用验证方法
              CheckLogin();
          }
      }
      /**//// summary
      /// 验证访问是否合法
      /// /summary
      private void CheckLogin()
      {
          // 判断当前访问页面是否需要进行验证
          if (IsValidateNeeded(Request.RawUrl))
          {
              // 如果 url中的编号 或 cookie中的编号
              if (string.IsNullOrEmpty(Request.QueryString["id"])
                  || string.IsNullOrEmpty(CookieUtil.ReadCookieByKey("id")))
              {
                  Response.Redirect("Login.aspx");
              }// 如果url中的编号 和 cookie中的编号 不匹配,返回登录页       
              else if (int.Parse(Request.QueryString["id"]) != int.Parse(CookieUtil.ReadCookieByKey("id")))
              {
                  Response.Redirect("Login.aspx");
              }
          }
      }
      /**//// summary
      /// 验证当前页是否需要验证
      /// /summary
      /// param name="currentPage"当前页面名称/param
      /// returns是否需要验证状态/returns
      private bool IsValidateNeeded(string url)
      {
          bool isNeeded = false;
          // GetValidatePages() 方法返回需要验证页面列表
          IListstring pages = XmlDAL.GetValidatePages();
          IEnumeratorstring ie = pages.GetEnumerator();
          while (ie.MoveNext())
          {
              // 如果当前页面需要进行验证
              if (url.Contains(ie.Current))
                  // 返回需要验证状态
                  return isNeeded = true;
          }
          return isNeeded;
      }
  }
  进行测试:
          步骤1:用 用户名zhangsan登录系统,登录成功,
                        页面显示 欢迎 zhangsan 登录。
                        url地址显示:
                        http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1001
          步骤2:手动修改url地址栏:如下:
                        http://localhost:3730/MasterPageBaseDemo/TestPage.aspx?id=1002
          页面不会显示 欢迎lisi登录,而是跳转回登录页面。

  至此我的代码迭代结束了。
  代码下载:
  http://www.cnblogs.com/Files/ayuan/MasterPageBaseDemo.rar
  本人之前没有写技术文章的经验,所以以上的文字难免晦涩,而且自身技术水平也有限,可能有些观点不太成熟,欢迎各位朋友指正。

来源:http://www.tulaoshi.com/n/20160219/1624901.html

延伸阅读
标签: 婴儿
宝宝不吃奶可以用什么来代替     宝宝们不喜欢吃奶的话,如果能够添加辅食的话,妈妈们就要想办法用一些食物来代替了,那么,用哪些食物可以代替宝宝们所需要的奶呢?下面就随图老师小编一起了解下吧。         一、酸奶,这是很多宝宝都爱喝的。      制作过程:酸奶是...
春天要来啦,猫猫又要开始换毛啦,那一大堆毛绒绒粘的到处都是猫毛到底该怎么处理呢。猫咪的毛可以是我们的大累赘,永远都打扫不干净,不过也可以变成可爱有趣的东西哦,比如用它的毛做戳戳乐,跟羊毛有的比嘿嘿,春天快来吧,让我多做几个戳戳乐~ 看,掉毛掉的很多吧~ 一根针,一个泡沫板...
标签: 洗面奶 洁面
淘米水洗脸 没有洗面奶而使用淘米水洗脸,能够帮助有效清洁肌肤并且清除皮肤中的含有的黑色素,美白肌肤同时柔嫩肌肤。 方法:将淘米用第2遍、第3遍水保存下来然后放置澄清后取最上面清澈的部分常规洗脸即可。 茶水洗脸 没有洗面奶而用茶水洗脸,其中茶叶水中含有大量的茶多酚等物质能有效对抗肌肤氧化,保持肌肤活力,特别...
标签: windows 操作系统
  如果你的手机有能和电脑连接的数据线,如果你用的操作系统是Windows XP,那么你就可以在电脑上输入短信并且发送了。 在Windows XP中发短信要用到的“SMS Sender”软件,它是Windows XP 的一个附加组件。跟普通发送短信的软件不同,“SMS Sender”只是为用户提供一种键入短消息的平台,而这些短消息还是通过手机来传输的,下面...
标签: Web开发
我们做WEB程序开发过程中,经常会为了Table中的cellSpacing,cellpadding等样式的设置发愁,经常没有办法可想了,就会直接在Table中设置cellSpacing,cellpadding了,这样以后要改页面风格时,或做多主题风格时,就会发现改起来是多么的痛苦了.奔着这个目标,经过不断的Google,终于把这个问题解决了,感谢Google,感谢热心的上传者,呵呵!现在把解决方法也...

经验教程

324

收藏

62
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部