Web应用的基本流程就是通过表单提交数据到服务器,服务器端程序以这些数据建立实体对象,经过处理后更新到数据库。而从表单数据创建实体对象的过程通常是很麻烦的,必须考虑到以下几点:
- 创建什么类型的对象?
- 表单的各项数据如何映射到对象的各项属性?
- 提交到服务器的数据都是字符串类型的,要还原成对应属性的数据类型。
之前我就用泛型写了一个Request工具类。不过这个类仅仅是解决了第三个问题而已,而要解决前两个问题就得靠反射了。
要解决第一个问题,还得用泛型,也就是类型作为参数传入,由此得到这个通用函数的原型:
public class ReqHelper
{
public static T GetEntity<T>()
{
}
}
而函数体的第一步,自然就是建立类型T的示例:
T entity = new T();
这段代码乍一看没错,但一编译就会报错,原因是编译器并不能确定T的构造函数的原型。因此还得用where关键字进一步约束T:
public static T GetEntity<T>() where T : new()
{
T entity = new T();
}
接着要知道类型T到底有哪些属性。这用Type类型的GetProperties方法就可以办到:
PropertyInfo[] pInfos = typeof(T).GetProperties();
下一步自然是从表单数据中获取对应属性的值并将其转换为对应的数据类型,这就需要遍历pInfos了:
string temp;
foreach (PropertyInfo pInfo in pInfos)
{
temp = HttpContext.Current.Request.Form[pInfo.Name];
if (temp != null)
{
try
{
pInfo.SetValue(entity, Convert.ChangeType(temp.Trim(), pInfo.PropertyType), null);
}
catch
{
}
}
}
最后就是返回entity,整个函数的完整代码如下:
public static T GetEntity<T>() where T : new()
{
T entity = new T();
string temp;
foreach (PropertyInfo pInfo in typeof(T).GetProperties())
{
temp = HttpContext.Current.Request.Form[pInfo.Name];
if (temp != null)
{
try
{
pInfo.SetValue(entity, Convert.ChangeType(temp.Trim(), pInfo.PropertyType), null);
}
catch
{
}
}
}
return entity;
}
由于反射是在运行时获取数据的,所以会有性能损失,最好对一些数据进行缓存。比如可以把GetProperties方法的返回值缓存下来,这样就无需每次都调用这个方法了。
评论 (1条)