本文實例講述了asp.net實現(xiàn)非常實用的自定義頁面基類。分享給大家供大家參考,具體如下:
看到前面幾篇文章(如:《asp.net實現(xiàn)利用反射,泛型,靜態(tài)方法快速獲取表單值到Model的方法》)想到的。下面總結(jié)發(fā)布一個筆者在開發(fā)中常用的一個自定義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鍵直接回發(fā)
/// /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); //遞歸調(diào)用
}
}
}
/// 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); //根據(jù)屬性,找到頁面對應控件,這要求頁面控件命名必須和對象的屬性一一對應相同
//下面取值
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); //根據(jù)屬性名取到頁面控件
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引發(fā)異常的方法:{1}\n錯誤信息:{2}\n錯誤堆棧:{3}\n",
this.Request.RawUrl, ex.TargetSite, ex.Message, ex.StackTrace);
return error;
}
#endregion
}
}
2、使用反射給控件賦值
根據(jù)id取一個員工(Employee),Employee類繼承自BaseObj類,根據(jù)這個客戶對象給頁面控件賦值:
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("在職狀態(tài):" + employee.State + "br/>");
this.ltrContext.Text = sb.ToString();
}
總結(jié):
(1)、對于頁面中控件較多的情況,這個類里的反射取值和賦值的方法還是很有用的(比較惡心的是你要哼唧哼唧地對照實體類給頁面控件命名。kao,實體類有代碼生成器自動生成我就忍了,頁面控件還要一一對應地命名,估計很多程序員在這方面沒少花時間,還有就是不考慮反射對性能的影響)。不過從代碼的簡潔程度來看,這個確實顯得out了;不過呢,筆者習慣了,命名多就多一些吧,在找到穩(wěn)定可靠的解決方案之前,短時間看來是不會選擇改進的了;
(2)、如果頁面中有用戶控件(UserControl),用戶控件里的子控件直接在頁面中就比較難取到了(你可能已經(jīng)看出問題的端倪來了),解決的方法就是在用戶控件里生成實體類(這個可以模仿BasePage寫一個BaseControl類,讓用戶控件繼承BaseControl,然后取值。本來想另開一篇介紹一下的,可是發(fā)現(xiàn)實現(xiàn)代碼雷同,放棄);
(3)、取消頁面文本框的enter key您可以參考《asp.net實現(xiàn)取消頁面表單內(nèi)文本輸入框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,這里簡陋地實現(xiàn)一個寫入文本日志類)
/// /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
這個比較無語。通常用來提供一個有好的出錯頁面。對于開發(fā)人員,建議顯示完整的異常信息。
下面貼一個對開發(fā)人員有幫助的頁面:
(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)、實現(xiàn)代碼
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寫到類庫里并在頁面上調(diào)用的具體方法
- 遞歸輸出ASP.NET頁面所有控件的類型和ID的代碼
- asp.net 簡單實現(xiàn)禁用或啟用頁面中的某一類型的控件
- asp.net 數(shù)據(jù)訪問層基類
- Asp.net 字符串操作基類(安全,替換,分解等)
- Asp.net 彈出對話框基類(輸出alet警告框)
- Asp.net 時間操作基類(支持短日期,長日期,時間差)
- Asp.Net 通用數(shù)據(jù)操作類 (附通用數(shù)據(jù)基類)
- Asp.Net+XML操作基類(修改,刪除,新增,創(chuàng)建)
- Asp.Net 文件操作基類(讀取,刪除,批量拷貝,刪除,寫入,獲取文件夾大小,文件屬性,遍歷目錄)