前言:
在项目开发过程中,有一项任务是我们要反复执行的:获取窗体控件的值,然后赋值到实体,再把实体值保存到数据库;load的时候,还有获取实体,再把实体属性值赋值到控件。如下所示:
1、获取窗体控件的值,然后赋值到实体
1 public partial class TestEdit : Page 2 { 3 private readonly StudentService service = new StudentService(); 4 private Student student = new Student(); 5 6 protected void Page_Load(object sender, EventArgs e) 7 { 8 if (!IsPostBack && !string.IsNullOrEmpty(Request["ID"])) 9 {10 student = service.GetStudentById(Request["ID"]);11 if (student == null)12 return;13 14 txtName.Text = student.Name;15 ddlSex.SelectedValue = student.Sex;16 txtAge.Text = student.Age.ToString();17 ddlDegree.SelectedValue = student.Degree;18 19 //省略其他20 }21 }22 23 protected void BtnSave_Click(object sender, EventArgs e)24 {25 26 student.Name = txtName.Text;27 student.Sex = ddlSex.SelectedValue;28 student.Age = int.Parse(txtAge.Text);29 student.Degree = ddlDegree.SelectedValue;30 //省略其他31 32 service.Save(student);33 }34 }
想象一下,如果1个表有几十上百个字段,这样赋值是多么繁琐的事情呀。
下面,我就跟大家讲一下,如果利用反射实现ASP.NET控件与实体之间的绑定,如果你还不熟悉反射,园子里关于反射的文章也比较多,可以去找。
正文:
一、下面先看一下利用反射后的代码:
1 public partial class TestEdit : Page 2 { 3 private readonly StudentService service = new StudentService(); 4 private Student student = new Student(); 5 6 protected void Page_Load(object sender, EventArgs e) 7 { 8 if (!IsPostBack && !string.IsNullOrEmpty(Request["ID"])) 9 {10 student = service.GetStudentById(Request["ID"]);11 ExtensionService.BindObjectToControls(student, this);12 }13 }14 15 protected void BtnSave_Click(object sender, EventArgs e)16 {17 ExtensionService.BindControlsToObject(student, this);18 service.Save(student);19 }20 }
通过前后代码的对比,是不是简洁了很多?
二、开始搭建我们的程序
说明:为了简单介绍这个例子,没有用ORM技术,直接用sql操作Access数据库
(1)、项目结构:
DBTest.accdb:为access数据库,有一个表TBL_Student,结构如下
DBHelper.cs:操作数据库帮助类
ExtensionService.cs:关键类,封装反射相关方法
Student.cs:实体类
StudentService.cs:Student服务类,操作Student实体
TestEdit.aspx:测试页面
(2)关键代码讲解
1、ExtensionService类主要包含2个方法,直接上代码
1 public static class ExtensionService 2 { 3 ///4 /// 将控件值绑定到业务对象 5 /// 6 /// 业务对象 7 /// 窗体或控件容器 8 public static void BindControlsToObject(object obj, Control container) 9 { 10 if (obj == null) return; 11 Type objType = obj.GetType(); 12 13 PropertyInfo[] objPropertyArray = objType.GetProperties(); 14 15 foreach (PropertyInfo propertyInfo in objPropertyArray) 16 { 17 //根据对象属性去查找控件 18 Control control = container.FindControl(propertyInfo.Name); 19 20 if (control == null) continue; 21 22 // ListControl是CheckBoxList、DropDownList、ListBox 和 RadioButtonList 的基类 23 if (control is ListControl) 24 { 25 var listControl = (ListControl)control; 26 if (listControl.SelectedItem != null) 27 { 28 var stringBuilder = new StringBuilder(); 29 for (int i = 0; i < listControl.Items.Count; i++) 30 { 31 if (listControl.Items[i].Selected) 32 { 33 stringBuilder.Append(listControl.Items[i].Value).Append(","); 34 } 35 } 36 37 Type propertyType = propertyInfo.PropertyType; 38 39 if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) 40 { 41 //判断是否为 System.Nullable 类型 42 propertyType = propertyType.GetGenericArguments()[0]; 43 44 if (string.IsNullOrEmpty(stringBuilder.ToString())) 45 { 46 propertyInfo.SetValue(obj, null, null); 47 continue; 48 } 49 } 50 object objValue = Convert.ChangeType(stringBuilder.ToString().Trim(','), propertyType); 51 propertyInfo.SetValue(obj, objValue, null); 52 } 53 } 54 else 55 { 56 Type controlType = control.GetType(); 57 PropertyInfo[] controlPropertyArray = controlType.GetProperties(); 58 59 GetControlProperty(obj, propertyInfo, control, controlPropertyArray); 60 61 } 62 } 63 } 64 65 ///66 /// 将对象值绑定到页面控件(进行中) 67 /// 68 /// 业务对象 69 /// 窗体或控件容器 70 public static void BindObjectToControls(object obj, Control container) 71 { 72 if (obj == null) return; 73 Type objType = obj.GetType(); 74 75 PropertyInfo[] objPropertyArray = objType.GetProperties(); 76 foreach (PropertyInfo propertyInfo in objPropertyArray) 77 { 78 //根据对象属性去查找控件 79 Control control = container.FindControl(propertyInfo.Name); 80 81 if (control == null) continue; 82 83 if (control is ListControl) 84 { 85 var listControl = (ListControl)control; 86 string propertyValue = propertyInfo.GetValue(obj, null).ToString(); 87 string[] values = propertyValue.Split(','); 88 if (values.Length == 0) continue; 89 90 foreach (string value in values) 91 { 92 ListItem listItem = listControl.Items.FindByValue(value); 93 if (listItem != null) 94 { 95 listItem.Selected = true; 96 } 97 } 98 } 99 else100 {101 Type controlType = control.GetType();102 PropertyInfo[] controlPropertyArray = controlType.GetProperties();103 SetControlProperty(obj, propertyInfo, control, controlPropertyArray);104 105 }106 }107 }108 109 ///110 /// 将实体对象的属性值赋值给页面控件111 /// 112 /// 113 /// 114 /// 115 /// 116 private static void SetControlProperty(object obj, PropertyInfo objProperty, Control control, IEnumerablecontrolPropertyArray)117 {118 Dictionary list = GetPropertyList();119 120 foreach (var dict in list)121 {122 // 在整个控件属性中进行迭代,检查控件匹配名称和类型的属性123 var propertys = from p in controlPropertyArray124 where p.Name == dict.Key && p.PropertyType == dict.Value125 select p;126 127 if (propertys.Count() == 0)128 continue;129 130 PropertyInfo controlProperty = propertys.First();131 132 controlProperty.SetValue(control, Convert.ChangeType(objProperty.GetValue(obj, null), dict.Value), null);133 134 }135 136 }137 138 /// 139 /// 获取页面控件的值,并赋值给实体对象140 /// 141 /// 142 /// 143 /// 144 /// 145 private static void GetControlProperty(object obj, PropertyInfo objProperty, Control control, IEnumerablecontrolPropertyArray)146 {147 //控件值属性集合及其类型148 Dictionary list = GetPropertyList();149 150 foreach (var dict in list)151 {152 // 检查控件匹配名称和类型的属性153 var propertys = from p in controlPropertyArray154 where p.Name == dict.Key && p.PropertyType == dict.Value155 select p;156 157 if (propertys.Count() == 0)158 continue;159 160 PropertyInfo controlProperty = propertys.First();161 // 将控件的属性设置为162 // 业务对象属性值163 Type propertyType = objProperty.PropertyType;164 165 try166 {167 //判断是否为 System.Nullable 类型168 if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))169 {170 propertyType = propertyType.GetGenericArguments()[0];171 172 if (string.IsNullOrEmpty(controlProperty.GetValue(control, null).ToString()))173 {174 //当属性的类型为 System.Nullable,且值为空/null时,设置属性值为null175 objProperty.SetValue(obj, null, null);176 177 //赋值成功时,退出循环178 break;179 }180 }181 182 object objValue = Convert.ChangeType(controlProperty.GetValue(control, null), propertyType);183 objProperty.SetValue(obj, objValue, null);184 //赋值成功时,退出循环185 break;186 187 }188 catch (Exception e)189 {190 throw new Exception(e.Message);191 }192 }193 }194 195 private static Dictionary GetPropertyList()196 {197 var list = new Dictionary ();198 list.Add("Checked", typeof(bool));199 list.Add("Value", typeof(String));200 list.Add("Text", typeof(String));201 return list;202 }203 }
如果不了解反射的人,建议先去学习反射相关内容
BindControlsToObject(object obj, Control container)将控件值绑定到业务对象,代码相关地方都有注释,这里就不介绍了。
BindObjectToControls(object obj, Control container)将对象值绑定到页面控件
2、TestEdit.aspx页面
1
4 用户名 5 | 6 7 | 9
12 性别13 | 1415 | 20
23 学位24 | 2526 | 33
36 爱好37 | 3839 | 45
48 年龄49 | 5051 | 53
56 | 58
需注意的是,控件的ID要与绑定对象的属性一样,如:<asp:TextBox runat="server" ID="Name"></asp:TextBox>,Name为Student的属性。
后台代码:
1 public partial class TestEdit : Page 2 { 3 private readonly StudentService service = new StudentService(); 4 private Student student = new Student(); 5 6 protected void Page_Load(object sender, EventArgs e) 7 { 8 if (!IsPostBack && !string.IsNullOrEmpty(Request["ID"])) 9 {10 student = service.GetStudentById(Request["ID"]);11 12 //将对象值绑定到页面控件13 ExtensionService.BindObjectToControls(student, this);14 }15 }16 17 protected void BtnSave_Click(object sender, EventArgs e)18 {19 //将控件值绑定到业务对象20 ExtensionService.BindControlsToObject(student, this);21 service.Save(student);22 }23 }
终于把相关的代码写完了O(∩_∩)O哈哈~,下面进行测试
3、测试
打开TestEdit.aspx,录入相关信息,如下图:
保存成功,Student表多了一条记录,如下:
最后,在地址栏输入,回车,刚才录入的数据就出来了
结束语:
第一次写博客,希望各位大牛指点。
作者:pengjunshe出处: