打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ASP.NET中采用Reflection机制把页面控件元素和对象联系起来。,ASP.NET...

最近在做一个项目,涉及到的实体很多,每个实体都需要做一个用户界面接受用户输入,这样在把实体对象展开到界面控件和从界面控件收集实体属性要写的代码就相当的多,但是这些代码都是简单的get和set操作。
于是我写了一个简单的赋值类:

using system;
using system.reflection;


/**
 * 文件名:web\assigner.cs
 * copyright(c):http://www.hakatasoft.com
 * 创建人:周树群
 * 日期:2004-10-16 18:45
 * 修改人:
 * 日期:
 * 描述:
 * 版本:1.0
 */
namespace sce.common.web {
 /// <summary>
 /// assigner 采用 reflection 机制简化了从 web 页面中的表单中构成对象
 /// 一般情况下:
 /// 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 来赋值
 /// 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 支持的类型
  /// <summary>
  /// 一些已知能处理的类型
  /// </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("不支持的数据类型。");
   }
  }


  /// <summary>
  /// 得到具有该名称的最合适的方法
  /// </summary>
  /// <param name="obj"></param>
  /// <param name="methodname"></param>
  /// <param name="onlytype">用来标识参数类型,传入一个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控件中的值赋值给对象
  /// 遍历给定的控件集合中的控件(包括子控件,跳过不具有指定前缀与后缀的 id 的控件。),
  /// 并将其值(textbox.text, dropdownlist.selectedvalue)赋给指定的对象。
  /// 例子:比如我们要把控件txtusernametextbox的值赋给user的username
  /// (obj拥有一个setusername(string username)方法),则使用:
  /// assign(page.controls, "txt", "textbox", user, "set", null);
  /// 如果user的username是采用类似下面的写法的:
  /// public string username {
  ///   get {
  ///     return m_username;
  ///   }
  ///   set {
  ///    m_username = value;
  ///  }
  /// }
  /// 那么采用这样的写法:
  /// sce.common.web.assigner.assign(page.controls, "txt", null, user, "set_", null);
  /// 因为这种getter,setter写法就类似与添加了set_xxx, get_xxx这样的方法。
  /// </summary>
  /// <param name="controls">web控件集合。</param>
  /// <param name="prefix">控件前缀,没有后缀用null或者""传入。</param>
  /// <param name="suffix">控件后缀,没有后缀用null或者""传入。</param>
  /// <param name="obj">需要赋值的对象。</param>
  /// <param name="setterprefix">赋值方法前缀,没有后缀用null或者""传入。</param>
  /// <param name="settersuffix">赋值方法后缀,没有后缀用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; // 参数类型
   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控件
  /// 遍历控件集合中的控件(包括控件的字控件,跳过不具有指定前缀与后缀的控件),把对象的值赋值给控件。
  /// </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


 }
}

对于其中的类型处理我觉得不是很好,因为我对c#还不是很熟悉,我参与使用asp.net开发的项目还是第一次,所以一些肯定还有相当大的改进的余地。
另外这种思想当然也可以用在其他的语言上,不一定是基于c#的asp.net。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
C# Form,Control 控件序列化
ExtJs 备忘录(3)—— Form表单(三) [ 数据验证 ]
WinForm跨线程UI操作常用控件类大全
在运行时通过鼠标拖动移动控件位置(c#)
SPGridview的webpart实例
ASP.NET TREEVIEW 使用方法(2) - yyf919 - 博客园
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服