asp. net implementation of a very practical custom page base class of with source code

  • 2021-07-07 07:00:44
  • OfStack

This article illustrates an example of asp. net implementation of a very useful custom page base class. Share it for your reference, as follows:

See the previous articles (for example, "asp. net Implementation of a Method for Quickly Getting Form Values to Model Using Reflection, Generics, and Static Methods"). The following summary releases a custom BasePage class commonly used in the development of the author, not much nonsense, directly paste the code.

1. Class BasePage

1. 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);//实例化1个类
   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);//从页面中取出满足某1个属性的字段
    if (fiPage != null) //页面的字段不为空,代表存在1个实例化的控件类
    {
     object value = null;
     Control pgControl = (Control)fiPage.GetValue(this); //根据属性,找到页面对应控件,这要求页面控件命名必须和对象的属性11对应相同
     //下面取值
     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. Assign values to controls using reflection

Take one employee (Employee) based on id, the Employee class inherits from the BaseObj class, and assign a value to the page control based on this customer object:


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 = " Beijing ", IsLeave = false, RealName = " Test user ", State = "2" };
    this.SetFormData(employee); // Assigning a value to a page control 
   }
  }
 }
}

3. Assign a value to an object using reflection

Click the "Test" button to assign the value of the page control (runat=server) to the entity object:


protected void btnSet_Click(object sender, EventArgs e)
{
 Employee employee = (Employee)this.GetFormData(typeof(Employee));
 StringBuilder sb = new StringBuilder();
 sb.Append(" Login name :" + employee.UserName + "<br/>");
 sb.Append(" Real name :" + employee.RealName + "<br/>");
 sb.Append(" Location :" + employee.Address + "<br/>");
 sb.Append(" Whether to leave :" + employee.IsLeave + "<br/>");
 sb.Append(" On-the-job status :" + employee.State + "<br/>");
 this.ltrContext.Text = sb.ToString();
}

Summary:

(1) For the case that there are many controls in the page, the reflection value taking and assignment methods in this class are still very useful (the disgusting thing is that you have to hum and hum to name the page controls against the entity class. kao, I will endure the automatic generation of entity classes by code generators, and the page controls will be named correspondingly. It is estimated that many programmers have spent no less time in this respect, and they do not consider the impact of reflection on performance. However, judging from the simplicity of the code, this does appear out; However, the author is used to naming more than 1. Before finding a stable and reliable solution, it seems that he will not choose to improve in a short time;
(2) If there is a user control (UserControl) in the page, it is difficult to get the child control in the user control directly in the page (you may have seen the clue of the problem). The solution is to generate an entity class in the user control (this can imitate BasePage to write an BaseControl class, let the user control inherit BaseControl, and then take the value. Originally, I wanted to open another article to introduce 1, but I found that the implementation code is similar and gave up);
(3) Cancel the enter key of the page text box. You can refer to "asp. net to cancel the Enter response of the text input box in the page form";
(4). See (2) for exception handling.

2. Exception handling

1. Log class (a simple and general text log processing class written by myself)


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
namespace DotNet.Common.WebForm
{
 /// <summary>
 ///  Log class ( Commonly used are log4net , implemented here in a rudimentary way 1 Write text log classes )
 /// </summary>
 public static class LogUtil
 {
  /// <summary>
  ///  Write exception log 
  /// </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

This one is speechless. Usually used to provide a page with good errors. For developers, it is recommended to display complete exception information.

Below is a helpful page for developers:

(1) Design page


<%@ 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> There's been a mistake </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) Implementation 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;
 }
}

Complete example code code click here to download this site.

I hope this paper is helpful to everyone's asp. net programming.


Related articles: