• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    asp.net实现非常实用的自定义页面基类(附源码)

    本文实例讲述了asp.net实现非常实用的自定义页面基类。分享给大家供大家参考,具体如下:

    看到前面几篇文章(如:《asp.net实现利用反射,泛型,静态方法快速获取表单值到Model的方法》)想到的。下面总结发布一个笔者在开发中常用的一个自定义BasePage类,废话不多说了,直接贴代码。

    一、BasePage类

    1、代码

    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(NullableDateTime>))) //泛型可空类型 
          {
           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类,根据这个客户对象给页面控件赋值:

    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)的值赋给实体对象:

    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、日志类(自己写的一个简单通用的文本日志处理类)

    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)、设计页面

    %@ 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)、实现代码

    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;
     }
    }
    
    

    完整实例代码代码点击此处本站下载。

    希望本文所述对大家asp.net程序设计有所帮助。

    您可能感兴趣的文章:
    • ASP.NET:把ashx写到类库里并在页面上调用的具体方法
    • 递归输出ASP.NET页面所有控件的类型和ID的代码
    • asp.net 简单实现禁用或启用页面中的某一类型的控件
    • asp.net 数据访问层基类
    • Asp.net 字符串操作基类(安全,替换,分解等)
    • Asp.net 弹出对话框基类(输出alet警告框)
    • Asp.net 时间操作基类(支持短日期,长日期,时间差)
    • Asp.Net 通用数据操作类 (附通用数据基类)
    • Asp.Net+XML操作基类(修改,删除,新增,创建)
    • Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)
    上一篇:asp.net实现取消页面表单内文本输入框Enter响应的方法
    下一篇:asp.net开发中常见公共捕获异常方式总结(附源码)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯

    时间:9:00-21:00 (节假日不休)

    地址:江苏信息产业基地11号楼四层

    《增值电信业务经营许可证》 苏B2-20120278

    asp.net实现非常实用的自定义页面基类(附源码) asp.net,实现,非常,实,用的,