关于ASP.NET中使用MasterPage和PageBase页面基类的一些体会
概念:MasterPage是ASP.NET中用于解决页面统一性的一个母版页,各个页面可以使用统一的MasterPage来规范页面风格。(MSDN注解)母版页用作 ASP.NET Web 应用程序中内容页的模板容器和合并页。母版页为在一组内容页之间共享结构和内容提供了一条方便的途径。可使用内容占位符定义母版页中要用内容页的内容加以替换的部分。
PageBase继承System.Web.UI.Page类,网站中的各个页面继承PageBase类,在PageBase类中可以做统一的逻辑控制
最近开发中涉及到MasterPage和PageBase的使用问题,WEB应用程序中的大多数页面都继承了MasterPage页面,具备统一的风格及部分代码逻辑,但是,也有一部分页面是需要特殊处理的并不需要继承MaterPage,比如一些弹出页面或特别处理的页面等等,这就需要另外再写一个页面基类来处理身份验证,URL参数控制,页面容错等逻辑,于是选择了PageBase,考虑到职责应该单一,让MasterPage只是处理跟界面统一风格有关的部分,而PageBase处理统一的逻辑控制,项目进行的还算顺利。
解决问题
但是不久后开发中又出现了另外一个问题,由于项目特殊性,需要我们的程序支持同一台机器可以同时登录两个用户,Session并不能很好的解决这个问题,于是我们设计了一个方案就是用户登录后其ID随URL存入页面上的一个隐藏文本框内,但这个TextBox放置的位置是个问题,因为系统中现有的页面一部分使用了MasterPage,一部分页面并没有使用MaterPage,如果在MasterPage中放置的话,有些页面会因为没有这个文本框而丢失用户信息了,于是我们让系统中的所有页面都继承了PageBase,并在PageBase中动态向当前页面添加TextBox控件来存储用户ID,当每个页面加载的时候基类会判断两个条件
添加控件:向页面添加TextBox来存储用户ID,需要先判断当前页面是否采用了母版页,
- 如果采用了母版页则在母版页的某个ContentPlaceHolder中放置一个TextBox,
- 如果没有采用则直接在页面的Form中添加TextBox,
如下图:
这样可以保证系统中所有采用PageBase作为基类的页面中都会含有这个文本框控件;
控件赋值:给页面中的TextBox赋值,
- 由于这种方法必须要求页面跳转是Server.Transfer或者控件PostBackUrl到服务器,所以需要判断页面的URL中是否有参数传入,因为用户登录或其他特定操作时ID将会作为URL传入,如果有参数则取得参数并赋值给当前页面的TextBox(这里需要判断本页是否采用了母版页,若采用则直接赋值给母版页中的TextBox,若没有采用则直接赋值给当前页面的TextBox)
- 如果没有参数则判断当前页面是否具备PreviousPage属性值,如果具备则判断PreviousPage是否采用了母版页并从页面上的TextBox中取值赋给当前页面中的TextBox,如果没有PreviousPage属性也没有URL参数值则终止赋值操作。
如图:
页面取值:我们可以写一个公共方法int GetUserID(this.Page)来取得当前页面的用户ID,这样的话只要牵扯到取得当前用户ID就可以直接调用方法来取了,并且节省了很多的代码。
取得页面TextBox值的公共方法如下:
至此,页面中必有这个控件,且控件中必然会有值,开发时可以在任何需要使用当前用户ID的地方直接调用GetUserID(this.Page)方法来取得当前页面的用户ID,从而实现了用户ID跟页面一起走的效果,避免了使用Session造成的会话覆盖。
这就是MasterPage和PageBase搭配完成的一个小功能:两个人可以同时使用一台电脑登录同一个系统。您有更好的方法么?