利用反射实现ASP.NET控件和数据实体之间的双向绑定,并且在客户端自动验证输入的内容是否合法...

首先请原谅我蹩脚的中文...玩电脑太多都不太会说话了,但愿大家看的明白 emembarrassed.gif

ASP.NET的UI不像做Winform那么容易,设个DataSource和DataField就什么都搞定了.虽然提供了<%#%>这样形式的绑定,但是这种绑定是单向的,只能从数据源赋值给控件,无法把控件的内容写回数据源.所以,在保存数据时得一条一条写,还得处理null,类型转换什么的.例如
anObject.AnIntProperty =  Convert.ToInt32(aControl.Text == "" ? aControl.Text  : "0"); //用数据实体的话
或者
aDatarow["AnIntField"] =  Convert.ToInt32(aControl.Text == "" ? aControl.Text  : "0"); //用datarow的话
有时一张表单几十个字段,这样写准会疯的 >_<

于是我利用反射做了一个东西,实现了让控件显示数据实体(我惯用o-r mapping而不是DataSet/DataRow,当然DataRow也能用类似的方式去搞)的内容和把控件的内容赋回给数据实体,然后,顺便把数据合法性验证也做进去了(反射性能损耗大,不干多点东西心里不平衡啊)

在我的BindingManager类中约定,凡是"_"结尾的控件将会被处理,这些控件会和实体类相对应的属性自动关联起来.通过设置PrefixLength的值指定从控件名的第几个字符开始匹配实体类属性,例如我习惯用3个字符做控件前缀,于是设PrefixLength为3,和Name属性关联的控件名就形如txtName_.然后调用GetEntityValues(Page,theObject)和SetEntityValue(Page,theObject)来实现控件和数据实体之间的绑定.

至于"顺便"做的合法性验证的功能,首先确保了控件输入的内容符合实体属性的类型,这是自动完成的,例如一个int属性对应的控件不能填写字母.如果有更多的要求,例如用正则表达式,不允许空值,或者在出错时给用户更详细的提示,则给实体的属性加上ValidateAttribute后就可以实现.

这是一个我写的Demo的其中一部分:Person类,其中有各种不同类型的属性.可以看到ValidateAttribute指定了Name不可空,描述为"姓名",这样,当 txtName_.Text 是空值时提交数据,将会弹出提示"姓名不能为空".而Id则规定了要输入现在新身份证的格式,如果不符合的话则提示"身份证号码格式不正确".另外,Sex是个自定义的类.得做个针对他的TypeConverter,然后给Sex类加上TypeConverterAttribute才可能被正确的处理.


None.gif      public   class  Person
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
public Person()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif                
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
string _name;
InBlock.gif        
decimal _height;
InBlock.gif        DateTime _birthday;
InBlock.gif        Sex _sex;
InBlock.gif        [Validate(AllowNull 
= false, Description = "姓名")]
InBlock.gif        
public string Name 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gif{return _name;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{_name = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif        [Validate(Description 
= "身高")]
InBlock.gif        
public decimal Height
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gif{return _height;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{_height = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif        
string _id;
InBlock.gif        [Validate(RegEx 
= "^\\d{17}(\\d|x)$", Description = "身份证号码")]
InBlock.gif        
public string Id 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gif{return _id;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{_id = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif            
InBlock.gif            
public DateTime Birthday
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gif{return _birthday;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{_birthday = value;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Sex Sex 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gif{return _sex;}
ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gif{_sex = value;}
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

在使用Person类时,一行语句就能实现控件和数据间赋值.以下是一个aspx后台代码的片断:
None.gif
None.gif        Person p 
=   new  Person();
None.gif        BindingManager bm 
=   new  BindingManager();
None.gif        
private   void  Page_Load( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif
InBlock.gif            
if (!IsPostBack) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//validateForm()是客户端验证控件合法性时调用的函数                       
InBlock.gif
                Button1.Attributes["onclick"= "return validateForm();"
InBlock.gif                
//给p随便设点值
InBlock.gif
                p.Name = "Yok";
InBlock.gif                p.Height 
= 170;
InBlock.gif                p.Sex 
= Sex.Male;
InBlock.gif                p.Birthday 
= new DateTime(19801121);
InBlock.gif                
//这样就可以让控件显示p的内容                
InBlock.gif
                bm.GetEntityValues(Page, p);
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

None.gif
None.gif        
private   void  Button1_Click( object  sender, System.EventArgs e)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//把值赋给实体
InBlock.gif
            bm.SetEntityValues(Page, p);
InBlock.gif            
//这时p已经从控件获得各个属性的值.Write出来看一下是否正确
InBlock.gif
            Response.Write("Name = " + p.Name + "<br>");
InBlock.gif            Response.Write(
"Height = " + p.Height + "<br>");
InBlock.gif            Response.Write(
"Birthday = " + p.Birthday.ToShortDateString() + "<br>");
InBlock.gif            Response.Write(
"Id = " + p.Id + "<br>");
InBlock.gif            Response.Write(
"Sex = " + p.Sex.ToString() + "<br>");
ExpandedBlockEnd.gif        }

None.gif


hitwall.gif不说了,我的 代码应该比我的文字好懂

转载于:https://www.cnblogs.com/Yok/archive/2004/11/23/67753.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值