Asp.Net WebForm 仿MVC ModelBinder功能
最近在做新加坡的一个项目,自己做了Tab控件,写了很多共通的东西。包括WebForm仿MVC ModelBinder功能。今天起了个早,写微博跟大家分享下,也请大家提出宝贵的意见。
去年学过Asp.Net MVC,里面有个非常有意思的功能,就是ModelBinder。它的表现形式是一方面VS会根据具体的某个Model类型生成相应的页面,另一方面VS也能将页面控件的值自动绑定到后台Model里(本人只知道怎么用,具体的原理说明不是很清楚,哪位博友可以分享这方面的文章)。当时觉得很好、很强大。在我接触的寥寥无几的几个项目中基本上是使用的WebForm模式。最初的做法就是手动的给服务器端控件复制或者将服务器端控件的值付给Model,这样很繁琐,做起来很烦,也很无趣。感觉自己就像coding的机器一样。
后来我想到了Asp.Net的反射技术,又查阅了关于Reflection的文章,于是写出了下面的两个静态方法。这两个方法放在工具类里面。
第一个方法是将Model的值自动付给服务器端控件,代码如下:
/// <summary> /// bind the properties to the page controls automatically /// @copyright gates.li /// </summary> /// <param name="listType">the type</param> /// <param name="page">the page object</param> public static void ModelAutoBindControls(IModel model,Page page) { Type listType = model.GetType(); //Get element properties and add datatable columns PropertyInfo[] properties = listType.GetProperties(); foreach (PropertyInfo property in properties) { string propertyName = property.Name; Control c = page.FindControl("tb" + propertyName); if (c != null) { TextBox tb = c as TextBox; if (tb != null) tb.Text = property.GetValue(model, null) == null ? "" : property.GetValue(model, null).ToString(); } else { c = page.FindControl("lb" + propertyName); Label label = c as Label; if (label != null) label.Text = property.GetValue(model, null) == null ? "" : property.GetValue(model, null).ToString(); } } }
第二个方法是将服务器端控件的值自动绑定到后台Model上,代码如下:
/// <summary> /// bind the values of the page controls to the model automatically /// @copyright gates.li /// </summary> /// <param name="model"></param> /// <param name="page"></param> public static void ControlsAutoBindModel(IModel model, Page page) { Type listType = model.GetType(); //Get element properties and add datatable columns PropertyInfo[] properties = listType.GetProperties(); foreach (PropertyInfo property in properties) { string propertyName = property.Name; Control c = page.FindControl("tb" + propertyName); if (c != null) { TextBox tb = c as TextBox; if (tb != null) { property.SetValue(model, tb.Text.Trim(), null); } } } }
大家仔细看上面的两个方法会发现IModel接口,这是我公司系统架构的体现。它是所有实体类的一个基类,具体代码如下:
public interface IModel { string validatemessage { get; set; } bool validate(); }
我们项目中的所有Model类是使用代码生成器生成,它们会自动实现该接口。
上面两个方法的原理很简单:两个遍历,一个约定。
两个遍历:
第一个遍历:传进去的Model的属性的遍历。
第二个遍历:页对象Page中Control的遍历。
一个约定:命名规则的约定
服务器端的TextBox控件命名规则是”tb”+Model的属性名。
服务器端的Label控件的名字是以”lb”+Model的属性名。
下次有机会分享自己开发的Tab Control。/tx