最近在做一個(gè)項目,涉及到的實(shí)體很多,每個(gè)實(shí)體都需要做一個(gè)用戶(hù)界面接受用戶(hù)輸入,這樣在把實(shí)體對象展開(kāi)到界面控件和從界面控件收集實(shí)體屬性要寫(xiě)的代碼就相當的多,但是這些代碼都是簡(jiǎn)單的get和set操作。
于是我寫(xiě)了一個(gè)簡(jiǎn)單的賦值類(lèi):
using system;
using system.reflection;
/**
* 文件名:web\assigner.cs
* copyright(c):http://www.hakatasoft.com
* 創(chuàng )建人:周樹(shù)群
* 日期:2004-10-16 18:45
* 修改人:
* 日期:
* 描述:
* 版本:1.0
*/
namespace sce.common.web {
/// <summary>
/// assigner 采用 reflection 機制簡(jiǎn)化了從 web 頁(yè)面中的表單中構成對象
/// 一般情況下:
/// system.web.ui.webcontrols.textbox txtmyfield1;
/// system.web.ui.webcontrols.textbox txtmyfield2;
/// myobject myobj = new myobject();
/// myobj.setmyfield1(txtmyfield1.text);
/// myobj.setmyfield2(txtmyfield2.text);
/// 采用 assigner 來(lái)賦值
/// system.web.ui.webcontrols.textbox txtmyfield1;
/// system.web.ui.webcontrols.textbox txtmyfield2;
/// myobject myobj = new myobject();
/// assigner.assign(page.controls(), "txt", null, myobj, "set", null);
/// </summary>
public class assigner {
private static readonly bool debug = false;
private assigner() {
}
#region 支持的類(lèi)型
/// <summary>
/// 一些已知能處理的類(lèi)型
/// </summary>
private static type[] knowntypes =
new type[]{
typeof(object),
typeof(string),
typeof(double),
typeof(float),
typeof(long),
typeof(int),
typeof(short),
typeof(char),
typeof(byte),
typeof(bool)
};
#endregion
#region
/// <summary>
/// 僅作調試
/// </summary>
/// <param name="s"></param>
private static void log(string s) {
if (debug) {
system.io.streamwriter sw = new system.io.streamwriter("c:\\tmp\\debug.log", true);
sw.writeline(s);
sw.close();
}
}
private static void setparam(object[] var, int index, object thevalue, type type) {
if (type.equals(typeof(object))) {
var[index] = thevalue;
}
else if(type.equals(typeof(string))) {
var[index] = thevalue.tostring();
}
else if(type.equals(typeof(double))) {
var[index] = double.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(float))) {
var[index] = float.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(long))) {
var[index] = long.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(int))) {
var[index] = int.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(short))) {
var[index] = short.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(char))) {
var[index] = char.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(byte))) {
var[index] = byte.parse(thevalue.tostring().trim());
}
else if(type.equals(typeof(bool))) {
var[index] = bool.parse(thevalue.tostring().trim());
}
else {
throw new system.applicationexception("不支持的數據類(lèi)型。");
}
}
/// <summary>
/// 得到具有該名稱(chēng)的最合適的方法
/// </summary>
/// <param name="obj"></param>
/// <param name="methodname"></param>
/// <param name="onlytype">用來(lái)標識參數類(lèi)型,傳入一個(gè)null即可</param>
/// <returns></returns>
private static system.reflection.methodinfo getonlymethodbyname(object obj, string methodname, ref type onlytype) {
methodinfo method = null;
type objtype = obj.gettype();
type[] types = new type[1];
for (int i = 0; i < knowntypes.length; i++) {
types.setvalue(knowntypes[i], 0);
method = objtype.getmethod(methodname, types);
if (method != null) {
break;
}
}
onlytype = types[0];
return method;
}
#endregion
#region 把web控件中的值賦給對象
/// <summary>
/// 把web控件中的值賦值給對象
/// 遍歷給定的控件集合中的控件(包括子控件,跳過(guò)不具有指定前綴與后綴的 id 的控件。),
/// 并將其值(textbox.text, dropdownlist.selectedvalue)賦給指定的對象。
/// 例子:比如我們要把控件txtusernametextbox的值賦給user的username
/// (obj擁有一個(gè)setusername(string username)方法),則使用:
/// assign(page.controls, "txt", "textbox", user, "set", null);
/// 如果user的username是采用類(lèi)似下面的寫(xiě)法的:
/// public string username {
/// get {
/// return m_username;
/// }
/// set {
/// m_username = value;
/// }
/// }
/// 那么采用這樣的寫(xiě)法:
/// sce.common.web.assigner.assign(page.controls, "txt", null, user, "set_", null);
/// 因為這種getter,setter寫(xiě)法就類(lèi)似與添加了set_xxx, get_xxx這樣的方法。
/// </summary>
/// <param name="controls">web控件集合。</param>
/// <param name="prefix">控件前綴,沒(méi)有后綴用null或者""傳入。</param>
/// <param name="suffix">控件后綴,沒(méi)有后綴用null或者""傳入。</param>
/// <param name="obj">需要賦值的對象。</param>
/// <param name="setterprefix">賦值方法前綴,沒(méi)有后綴用null或者""傳入。</param>
/// <param name="settersuffix">賦值方法后綴,沒(méi)有后綴用null或者""傳入。</param>
public static void assign(system.web.ui.controlcollection controls, string prefix, string suffix, system.object obj, string setterprefix, string settersuffix) {
if (null == prefix) {
prefix = "";
}
if (null == suffix) {
suffix = "";
}
if (null == setterprefix) {
setterprefix = "";
}
if (null == settersuffix) {
settersuffix = "";
}
system.collections.ienumerator myenum = controls.getenumerator();
string ctrlid, field, methodname;
object thevalue;
system.web.ui.control ctrl;
type type = obj.gettype();
system.reflection.methodinfo method = null;
object[] parameters; // 參數值
type[] types; // 參數類(lèi)型
while (myenum.movenext()) {
ctrl = (system.web.ui.control) myenum.current;
ctrlid = ctrl.id;
if (ctrl.hascontrols()) {
assign(ctrl.controls, prefix, suffix, obj, setterprefix, settersuffix);
}
if(
ctrlid != null
&&
(ctrlid.startswith(prefix) || prefix.length == 0)
&&
(ctrlid.endswith(suffix) || suffix.length == 0)
) {
// field
field = ctrlid.substring(prefix.length, ctrlid.length - prefix.length - suffix.length);
methodname = setterprefix + field + settersuffix;
// types
types = new type[1];
// try to find the only method
/*
for (int i = 0; i < knowntypes.length; i++) {
types.setvalue(knowntypes[i], 0);
method = type.getmethod(methodname, types);
if (method != null) {
break;
}
}
*/
type onlytype = null;
method = getonlymethodbyname(obj, methodname, ref onlytype);
// assign value
if (method != null) {
//log(method.tostring());
// value
if (ctrl is system.web.ui.webcontrols.textbox) {
thevalue = ((system.web.ui.webcontrols.textbox)ctrl).text;
}
else if(ctrl is system.web.ui.webcontrols.dropdownlist) {
thevalue = ((system.web.ui.webcontrols.dropdownlist)ctrl).selectedvalue;
}
else if(ctrl is system.web.ui.webcontrols.checkbox) {
thevalue = ((system.web.ui.webcontrols.checkbox)ctrl).checked;
}
else if(ctrl is system.web.ui.webcontrols.checkboxlist) {
thevalue = ((system.web.ui.webcontrols.checkboxlist)ctrl).selectedvalue;
}
else {
thevalue = "";
}
// parameters
parameters = new object[1];
if (thevalue != null && thevalue.tostring().length != 0) {
setparam(parameters, 0, thevalue, onlytype);
method.invoke(obj, parameters);
}
}
}
}
}
#endregion
#region 把對象的值賦給web控件
/// <summary>
/// 把對象的值賦值給web控件
/// 遍歷控件集合中的控件(包括控件的字控件,跳過(guò)不具有指定前綴與后綴的控件),把對象的值賦值給控件。
/// </summary>
/// <param name="obj">提供值的對象</param>
/// <param name="getterprefix">getter前綴</param>
/// <param name="gettersuffix">getter后綴</param>
/// <param name="controls">web控件集合</param>
/// <param name="prefix">控件id前綴</param>
/// <param name="suffix">控件id后綴</param>
public static void assign(system.object obj, string getterprefix, string gettersuffix, system.web.ui.controlcollection controls, string prefix, string suffix) {
if (null == prefix) {
prefix = "";
}
if (null == suffix) {
suffix = "";
}
if (null == getterprefix) {
getterprefix = "";
}
if (null == gettersuffix) {
gettersuffix = "";
}
system.collections.ienumerator myenum = controls.getenumerator();
type type = obj.gettype();
system.web.ui.control ctrl;
system.reflection.methodinfo method = null;
system.web.ui.webcontrols.dropdownlist dropdownlist;
system.web.ui.webcontrols.checkboxlist checkboxlist;
object retobj;
string ret, ctrlid, field, methodname;
while (myenum.movenext()) {
ctrl = (system.web.ui.control) myenum.current;
ctrlid = ctrl.id;
if (ctrl.hascontrols()) {
assign(obj, getterprefix, gettersuffix,ctrl.controls, prefix, suffix);
}
if(
ctrlid != null
&&
(ctrlid.startswith(prefix) || prefix.length == 0)
&&
(ctrlid.endswith(suffix) || suffix.length == 0)
) {
// field
field = ctrlid.substring(prefix.length, ctrlid.length - prefix.length - suffix.length);
methodname = getterprefix + field + gettersuffix;
// try to find the only method
method = type.getmethod(methodname);
if (method != null) {
retobj = method.invoke(obj, new object[0]);
ret = (retobj == null ? "" : retobj.tostring());
if (ctrl is system.web.ui.webcontrols.textbox) {
((system.web.ui.webcontrols.textbox)ctrl).text = ret.tostring();
}
else if(ctrl is system.web.ui.webcontrols.checkbox) {
((system.web.ui.webcontrols.checkbox)ctrl).checked = bool.parse(ret);
}
else if(ctrl is system.web.ui.webcontrols.dropdownlist) {
dropdownlist = (system.web.ui.webcontrols.dropdownlist)ctrl;
if (dropdownlist.items.findbyvalue(ret) != null) {
dropdownlist.selectedvalue = ret;
}
}
else if(ctrl is system.web.ui.webcontrols.checkboxlist) {
checkboxlist = (system.web.ui.webcontrols.checkboxlist)ctrl;
if (checkboxlist.items.findbyvalue(ret) != null) {
checkboxlist.selectedvalue = ret;
}
}
//ctrl.databind();
}
}
}
}
#endregion
}
}
對于其中的類(lèi)型處理我覺(jué)得不是很好,因為我對c#還不是很熟悉,我參與使用asp.net開(kāi)發(fā)的項目還是第一次,所以一些肯定還有相當大的改進(jìn)的余地。
另外這種思想當然也可以用在其他的語(yǔ)言上,不一定是基于c#的asp.net。
聯(lián)系客服