非常实用的自定义asp.net页面基类

看到园子里几篇文章(如: 利用反射,泛型,静态方法快速获取表单值到Model)想到的。下面总结发布一个笔者在开发中常用的一个自定义BasePage类,废话不多说了,直接贴代码。
一、BasePage类
1、代码
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Reflection;

namespace DotNet.Common.WebForm
{
    
using DotNet.Common.Model;
    
using DotNet.Common.Util;

    
public class BasePage : System.Web.UI.Page
    {
        
public BasePage()
        {
        }

        
protected override void OnInit(EventArgs e)
        {
            
base.OnInit(e);
            
//CancelFormControlEnterKey(this.Page.Form.Controls); //取消页面文本框的enter key
        }

        
#region 取消页面文本控件的enter key功能

        
/// <summary>
        
/// 在这里我们给Form中的服务器控件添加客户端onkeydown脚步事件,防止服务器控件按下enter键直接回发
        
/// </summary>
        
/// <param name="controls"></param>
        public virtual void CancelFormControlEnterKey(ControlCollection controls)
        {
            
//向页面注册脚本 用来取消input的enter key功能
            RegisterUndoEnterKeyScript();

            
foreach (Control item in controls)
            {
                
//服务器TextBox
                if (item.GetType() == typeof(System.Web.UI.WebControls.TextBox))
                {
                    WebControl webControl 
= item as WebControl;
                    webControl.Attributes.Add(
"onkeydown""return forbidInputKeyDown(event)");
                }
                
//html控件
                else if (item.GetType() == typeof(System.Web.UI.HtmlControls.HtmlInputText))
                {
                    HtmlInputControl htmlControl 
= item as HtmlInputControl;
                    htmlControl.Attributes.Add(
"onkeydown""return forbidInputKeyDown(event)");
                }
                
//用户控件
                else if (item is System.Web.UI.UserControl)
                {
                    CancelFormControlEnterKey(item.Controls); 
//递归调用
                }
            }
        }

        
/// <summary>
        
/// 向页面注册forbidInputKeyDown脚本
        
/// </summary>
        private void RegisterUndoEnterKeyScript()
        {
            
string js = string.Empty;
            System.Text.StringBuilder sb 
= new System.Text.StringBuilder();
            sb.Append(
"function forbidInputKeyDown(ev) {");
            sb.Append(
"  if (typeof (ev) != \"undefined\") {");

            sb.Append(
"  if (ev.keyCode || ev.which) {");
            sb.Append(
"   if (ev.keyCode == 13 || ev.which == 13) { return false; }");
            sb.Append(
"  } } }");
            js 
= sb.ToString();
            
if (!this.Page.ClientScript.IsClientScriptBlockRegistered("forbidInput2KeyDown"))
                
this.Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "forbidInput2KeyDown", js, true);
        }

        
#endregion

        
#region 利用反射取/赋页面控件的值

        
/// <summary>
        
/// 从页面中取控件值,并给对象赋值
        
/// </summary>
        
/// <param name="dataType">要被赋值的对象类型</param>
        
/// <returns></returns>
        public virtual BaseObj GetFormData(Type dataType)
        {
            BaseObj data 
= (BaseObj)Activator.CreateInstance(dataType);//实例化一个类
            Type pgType = this.GetType(); //标识当前页面
            BindingFlags bf = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic;//反射标识
            PropertyInfo[] propInfos = data.GetType().GetProperties();//取出所有公共属性 
            foreach (PropertyInfo item in propInfos)
            {
                FieldInfo fiPage 
= pgType.GetField(item.Name, bf);//从页面中取出满足某一个属性的字段
                if (fiPage != null//页面的字段不为空,代表存在一个实例化的控件类
                {
                    
object value = null;
                    Control pgControl 
= (Control)fiPage.GetValue(this); //根据属性,找到页面对应控件,这要求页面控件命名必须和对象的属性一一对应相同

                    
//下面取值
                    Type controlType = pgControl.GetType();
                    
if (controlType == typeof(Label))
                    {
                        value 
= ((Label)pgControl).Text.Trim();
                    }
                    
else if (controlType == typeof(TextBox))
                    {
                        value 
= ((TextBox)pgControl).Text.Trim();
                    }
                    
else if (controlType == typeof(HtmlInputText))
                    {
                        value 
= ((HtmlInputText)pgControl).Value.Trim();
                    }
                    
else if (controlType == typeof(HiddenField))
                    {
                        value 
= ((HiddenField)pgControl).Value.Trim();
                    }
                    
else if (controlType == typeof(CheckBox))
                    {
                        value 
= (((CheckBox)pgControl).Checked);//复选框
                    }
                    
else if (controlType == typeof(DropDownList))//下拉框
                    {
                        value 
= ((DropDownList)pgControl).SelectedValue;
                    }
                    
else if (controlType == typeof(RadioButtonList))//单选框列表
                    {
                        value 
= ((RadioButtonList)pgControl).SelectedValue;
                        
if (value != null)
                        {
                            
if (value.ToString().ToUpper() != "TRUE" && value.ToString().ToUpper() != "FALSE")
                                value 
= value.ToString() == "1" ? true : false;
                        }

                    }
                    
else if (controlType == typeof(Image)) //图片
                    {
                        value 
= ((Image)pgControl).ImageUrl;
                    }
                    
try
                    {
                        
object realValue = null;
                        
if (item.PropertyType.Equals(typeof(Nullable<DateTime>))) //泛型可空类型 
                        {
                            
if (value != null)
                            {
                                
if (string.IsNullOrEmpty(value.ToString()))
                                {
                                    realValue 
= null;
                                }
                                
else
                                {
                                    realValue 
= DateTime.Parse(value.ToString());
                                }
                            }
                        }
                        
else if (item.PropertyType.Equals(typeof(Nullable))) //可空类型 
                        {
                            realValue 
= value;
                        }
                        
else
                        {
                            
try
                            {
                                realValue 
= Convert.ChangeType(value, item.PropertyType);
                            }
                            
catch
                            {
                                realValue 
= null;
                            }
                        }
                        item.SetValue(data, realValue, 
null);
                    }
                    
catch (FormatException fex)
                    {
                        DotNet.Common.Util.Logger.WriteFileLog(fex.Message, HttpContext.Current.Request.PhysicalApplicationPath 
+ "LogFile");
                        
throw fex;
                    }
                    
catch (Exception ex)
                    {
                        DotNet.Common.Util.Logger.WriteFileLog(ex.Message, HttpContext.Current.Request.PhysicalApplicationPath 
+ "LogFile");
                        
throw ex;
                    }
                }
            }
            
return data;
        }

        
/// <summary>
        
/// 通过对象的属性值,给页面控件赋值
        
/// </summary>
        
/// <param name="data"></param>
        public virtual void SetFormData(BaseObj data)
        {
            Type pgType 
= this.GetType();
            BindingFlags bf 
= BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
            PropertyInfo[] propInfos 
= data.GetType().GetProperties();
            
foreach (PropertyInfo item in propInfos)
            {
                FieldInfo myField 
= pgType.GetField(item.Name, bf);
                
if (myField != null)
                {
                    Control myControl 
= (Control)myField.GetValue(this); //根据属性名取到页面控件
                    object value = item.GetValue(data, null); //取对象的属性值
                    Type propType = item.PropertyType;

                    
if (value != null)
                    {
                        Type valueType 
= value.GetType();
                        
try
                        {
                            Type controlType 
= myControl.GetType();
                            
if (controlType == typeof(Label))
                            {
                                
if (valueType == typeof(DateTime))
                                {
                                    ((Label)myControl).Text 
= (Convert.ToDateTime(value)).ToShortDateString();
                                }
                                
else
                                {
                                    ((Label)myControl).Text 
= value.ToString();
                                }

                            }
                            
else if (controlType == typeof(TextBox))
                            {
                                
if (valueType == typeof(DateTime))
                                {
                                    ((TextBox)myControl).Text 
= (Convert.ToDateTime(value)).ToShortDateString();
                                }
                                
else
                                {
                                    ((TextBox)myControl).Text 
= value.ToString();
                                }
                            }
                            
else if (controlType == typeof(HtmlInputText))
                            {
                                
if (valueType == typeof(DateTime))
                                {
                                    ((HtmlInputText)myControl).Value 
= (Convert.ToDateTime(value)).ToShortDateString();
                                }
                                
else
                                {
                                    ((HtmlInputText)myControl).Value 
= value.ToString();
                                }
                            }
                            
else if (controlType == typeof(HiddenField))
                            {
                                ((HiddenField)myControl).Value 
= value.ToString();
                            }
                            
else if (controlType == typeof(CheckBox))
                            {
                                
if (valueType == typeof(Boolean)) //布尔型
                                {
                                    
if (value.ToString().ToUpper() == "TRUE")
                                        ((CheckBox)myControl).Checked 
= true;
                                    
else
                                        ((CheckBox)myControl).Checked 
= false;
                                }
                                
else if (valueType == typeof(Int32)) //整型 (正常情况下,1标识选择,0标识不选)
                                {
                                    ((CheckBox)myControl).Checked 
= string.Compare(value.ToString(), "1"== 0;
                                }

                            }
                            
else if (controlType == typeof(DropDownList))
                            {
                                
try
                                {
                                    ((DropDownList)myControl).SelectedValue 
= value.ToString();
                                }
                                
catch
                                {
                                    ((DropDownList)myControl).SelectedIndex 
= -1;
                                }
                            }
                            
else if (controlType == typeof(RadioButton))
                            {
                                
if (valueType == typeof(Boolean)) //布尔型
                                {
                                    
if (value.ToString().ToUpper() == "TRUE")
                                        ((RadioButton)myControl).Checked 
= true;
                                    
else
                                        ((RadioButton)myControl).Checked 
= false;
                                }
                                
else if (valueType == typeof(Int32)) //整型 (正常情况下,1标识选择,0标识不选)
                                {
                                    ((RadioButton)myControl).Checked 
= string.Compare(value.ToString(), "1"== 0;
                                }
                            }
                            
else if (controlType == typeof(RadioButtonList))
                            {
                                
try
                                {
                                    
if (valueType == typeof(Boolean)) //布尔型
                                    {
                                        
if (value.ToString().ToUpper() == "TRUE")
                                            ((RadioButtonList)myControl).SelectedValue 
= "1";
                                        
else
                                            ((RadioButtonList)myControl).SelectedValue 
= "0";
                                    }
                                    
else
                                        ((RadioButtonList)myControl).SelectedValue 
= value.ToString();
                                }
                                
catch
                                {
                                    ((RadioButtonList)myControl).SelectedIndex 
= -1;
                                }

                            }
                            
else if (controlType == typeof(Image))
                            {
                                ((Image)myControl).ImageUrl 
= value.ToString();
                            }
                        }
                        
catch (FormatException fex)
                        {
                            DotNet.Common.Util.Logger.WriteFileLog(fex.Message, HttpContext.Current.Request.PhysicalApplicationPath 
+ "LogFile");
                        }
                        
catch (Exception ex)
                        {
                            DotNet.Common.Util.Logger.WriteFileLog(ex.Message, HttpContext.Current.Request.PhysicalApplicationPath 
+ "LogFile");
                        }
                    }
                }
            }
        }

        
#endregion

        
#region 日志处理

        
/// <summary>
        
/// 出错处理:写日志,导航到公共出错页面
        
/// </summary>
        
/// <param name="e"></param>
        protected override void OnError(EventArgs e)
        {
            Exception ex 
= this.Server.GetLastError();
            
string error = this.DealException(ex);
            DotNet.Common.Util.Logger.WriteFileLog(error, HttpContext.Current.Request.PhysicalApplicationPath 
+ "LogFile");
            
if (ex.InnerException != null)
            {
                error 
= this.DealException(ex);
                DotNet.Common.Util.Logger.WriteFileLog(error, HttpContext.Current.Request.PhysicalApplicationPath 
+ "LogFile");
            }
            
this.Server.ClearError();
            
this.Response.Redirect("/Error.aspx");
        }

        
/// <summary>
        
/// 处理异常,用来将主要异常信息写入文本日志
        
/// </summary>
        
/// <param name="ex"></param>
        
/// <returns></returns>
        private string DealException(Exception ex)
        {
            
this.Application["StackTrace"= ex.StackTrace;
            
this.Application["MessageError"= ex.Message;
            
this.Application["SourceError"= ex.Source;
            
this.Application["TargetSite"= ex.TargetSite.ToString();
            
string error = string.Format("URl:{0}\n引发异常的方法:{1}\n错误信息:{2}\n错误堆栈:{3}\n",
                
this.Request.RawUrl, ex.TargetSite, ex.Message, ex.StackTrace);
            
return error;
        }

        
#endregion
    }
}
2、使用反射给 控件赋值
根据id取一个员工(Employee),Employee类继承自BaseObj类,根据这个客户对象给页面控件赋值:
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Threading;

namespace WebTest
{
    
using DotNet.Common.WebForm;
    
using DotNet.Common.Model;
    
using EntCor.Hrm.Model;

    
public partial class _Default : BasePage
    {
        
protected void Page_Load(object sender, EventArgs e)
        {
            
if (!IsPostBack)
            {
                Employee employee 
= new Employee { ID = 1, UserName = "jeff wong", Address = "北京", IsLeave = false, RealName = "测试用户", State = "2" };
                
this.SetFormData(employee); //给页面控件赋值
            }
        }
    }
}
3、使用反射给 对象赋值
点击”测试”按钮,将页面控件(runat=server)的值赋给实体对象:
ContractedBlock.gif ExpandedBlockStart.gif Code
  protected void btnSet_Click(object sender, EventArgs e)
        {
            Employee employee 
= (Employee)this.GetFormData(typeof(Employee));
            StringBuilder sb 
= new StringBuilder();
            sb.Append(
"登录名:" + employee.UserName + "<br/>");
            sb.Append(
"真实姓名:" + employee.RealName + "<br/>");
            sb.Append(
"所在地:" + employee.Address + "<br/>");
            sb.Append(
"是否离职:" + employee.IsLeave + "<br/>");
            sb.Append(
"在职状态:" + employee.State + "<br/>");

            
this.ltrContext.Text = sb.ToString();

        }
总结:
(1)、对于页面中控件较多的情况,这个类里的反射取值和赋值的方法还是很有用的(比较恶心的是你要哼唧哼唧地对照实体类给页面控件命名。kao,实体类有代码生成器自动生成我就忍了,页面控件还要一一对应地命名,估计很多程序员在这方面没少花时间,还有就是不考虑反射对性能的影响)。不过从代码的简洁程度来看,这个确实显得out了;不过呢,笔者习惯了,命名多就多一些吧,在找到稳定可靠的解决方案之前,短时间看来是不会选择改进的了;
(2)、如果页面中有用户控件(UserControl),用户控件里的子控件直接在页面中就比较难取到了(你可能已经看出问题的端倪来了),解决的方法就是在用户控件里生成实体类(这个可以模仿BasePage写一个BaseControl类,让用户控件继承BaseControl,然后取值。本来想另开一篇介绍一下的,可是发现实现代码雷同,放弃);
(3)、取消页面文本框的enter key您可以参考“ asp.net取消页面表单内文本输入框的Enter响应”;
(4)、异常处理见(二)。
二、异常处理
1、日志类(自己写的一个简单通用的文本日志处理类)
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;

namespace DotNet.Common.WebForm
{
    
/// <summary>
    
/// 日志类(常用的都是log4net,这里简陋地实现一个写入文本日志类)
    
/// </summary>
    public static class LogUtil
    {
        
/// <summary>
        
/// 写入异常日志
        
/// </summary>
        
/// <param name="ex"></param>
        public static void WriteFileLog(string exMsg)
        {
            
string path = HttpContext.Current.Request.PhysicalApplicationPath + "LogFile";
            FileStream fs 
= null;
            StreamWriter m_streamWriter 
= null;
            
try
            {
                
if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                path 
= path + "\\" + DateTime.Now.ToString("yyyyMMdd"+ ".txt";
                fs 
= new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
                m_streamWriter 
= new StreamWriter(fs);
                m_streamWriter.BaseStream.Seek(
0, SeekOrigin.End);
                m_streamWriter.WriteLine(DateTime.Now.ToString() 
+ "\n");
                m_streamWriter.WriteLine(
"-----------------------------------------------------------");
                m_streamWriter.WriteLine(
"-----------------------------------------------------------");
                m_streamWriter.WriteLine(exMsg);
                m_streamWriter.WriteLine(
"-----------------------------------------------------------");
                m_streamWriter.WriteLine(
"-----------------------------------------------------------");
                m_streamWriter.Flush();
            }
            
finally
            {
                
if (m_streamWriter != null)
                {
                    m_streamWriter.Close();
                }
                
if (fs != null)
                {
                    fs.Close();
                }
            }
        }
    }
}
2、Error.aspx
这个比较无语。通常用来提供一个有好的出错页面。对于开发人员,建议显示完整的异常信息。
下面贴一个对开发人员有帮助的页面:
(1)、设计页面
ContractedBlock.gif ExpandedBlockStart.gif Code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Error.aspx.cs" Inherits="Error" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    
<title>出错啦</title>
</head>
<body>
    
<form id="form1" runat="server">
    
<div>
        
<table width='100%' align='center' style='font-size: 10pt; font-family: Trebuchet MS, Arial'>
            
<tr align='center'>
                
<td align="center" colspan="2">
                    
<b>Error on page</b>
                
</td>
            
</tr>
            
<tr>
                
<td align='right' width="200">
                    
<b>stackTrace :</b>
                
</td>
                
<td align='left'>
                    
<asp:Label ID="lblStackTrace" runat="server"></asp:Label>
                
</td>
            
</tr>
            
<tr>
                
<td align='right'>
                    
<b>Error message :</b>
                
</td>
                
<td align='left'>
                    
<asp:Label ID="lblMessageError" runat="server"></asp:Label>
                
</td>
            
</tr>
            
<tr>
                
<td align='right'>
                    
<b>Source :</b>
                
</td>
                
<td align='left'>
                    
<asp:Label ID="lblSourceError" runat="server"></asp:Label>
                
</td>
            
</tr>
            
<tr>
                
<td align='right'>
                    
<b>TargetSite :</b>
                
</td>
                
<td align='left'>
                    
<asp:Label ID="lblTagetSiteError" runat="server"></asp:Label>
                
</td>
            
</tr>
        
</table>
    
</div>
    
</form>
</body>
</html>
(2)、实现代码
ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class ErrorPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.lblStackTrace.Text = this.Application["StackTrace"] as string;
        this.lblMessageError.Text = this.Application["MessageError"] as string;
        this.lblSourceError.Text = this.Application["SourceError"] as string;
        this.lblTagetSiteError.Text = this.Application["TargetSite"] as string;
    }
}
好了,就总结到这里,希望对您有帮助。
实例下载: Demo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值