博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用反射实现页面控件与实体之间的绑定
阅读量:6735 次
发布时间:2019-06-25

本文共 13346 字,大约阅读时间需要 44 分钟。

前言:

     在项目开发过程中,有一项任务是我们要反复执行的:获取窗体控件的值,然后赋值到实体,再把实体值保存到数据库;load的时候,还有获取实体,再把实体属性值赋值到控件。如下所示:

 1、获取窗体控件的值,然后赋值到实体

View Code
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控件与实体之间的绑定,如果你还不熟悉反射,园子里关于反射的文章也比较多,可以去找。

 

正文:

    一、下面先看一下利用反射后的代码:   

View Code
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个方法,直接上代码

View Code
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, IEnumerable
controlPropertyArray)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, IEnumerable
controlPropertyArray)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页面

View Code
1         
2
3
6
9
10
11
14
20
21
22
25
33
34
35
38
45
46
47
50
53
54
55
58
59
4 用户名 5 7
8
12 性别13 15
16
17
18
19
23 学位24 26
27
28
29
30
31
32
36 爱好37 39
40
篮球
41
排球
42
奶茶
43
44
48 年龄49 51
52
56
57

 

需注意的是,控件的ID要与绑定对象的属性一样,如:<asp:TextBox runat="server" ID="Name"></asp:TextBox>,Name为Student的属性。

后台代码:

View Code
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

出处:

转载于:https://www.cnblogs.com/pengjunshe/archive/2012/08/04/2621419.html

你可能感兴趣的文章
宏内核与微内核【转】
查看>>
笔记︱集成学习Ensemble Learning与树模型、Bagging 和 Boosting
查看>>
内存回收
查看>>
error LNK1104:无法打开文件"lua51.lib"
查看>>
Git 详细的操作指南笔记
查看>>
尼采语录
查看>>
【linux】crontab失效
查看>>
利用Sharding-Jdbc实现分表
查看>>
php post接口,登录功能
查看>>
xml学习_上篇
查看>>
Java下利用Jackson进行JSON解析和序列化
查看>>
HTML5标准学习 - 文档结构
查看>>
2018年前端面试题(秋季面试随意整理的)
查看>>
深圳Android技术大会分享
查看>>
requestAnimationFrame 兼容方案
查看>>
Java™ 教程(管理源文件和类文件)
查看>>
Linux运维之路-安全防护OpenResty
查看>>
说说不知道的Golang中参数传递
查看>>
深入解析Vue底层实现原理
查看>>
es6之解构赋值
查看>>