深入ASP.NET数据绑定(下)——多样的绑定方式

上一篇 / 下一篇  2008-05-05 23:56:41 / 个人分类:转载

在这个系列的上篇中介绍了数据绑定语法的原理以及.NET中如何实现单向绑定,中篇我 们简单的介绍了ASP.NET 2.0 中新增的Bind语法配合DataSourceControl来实现数据的自动双向绑定。这两部分的内容相对动态抽象并且不常接触,没有很好的源代码支持 很难解释清楚,要想真正弄清它们的内部原理,还需要大家亲自动手去反编译分析动态编译的程序集。

在了解了数据绑定语法的原理后,我还想来 谈谈我中实践过程中遇到的一些问题以及其它实用的绑定技巧。首先我们就来说说,特殊字段名的问题。我们知道在数据库当中,如果表名或字段名中包含有一些特 殊的不能是合法的字符时,都会使用[]将它们引起来,以便他们能够正常使用。但是在<%# Eval("")%>的绑定语句当中,同时可以使用[],但是对于字段名中包含 "(",")","[","]"这4个字符却始终运行出错。假设像我下面这样来绑定"电压(V)":

<%#Eval("电压(V)")%>
那么就会得到一个运行时错误:
DataBinding:“System.Data.DataRowView”不包含名为“电压”的属性。
表明括号是被认为是一个特殊字符,那我们如果给字段名加上[],如下:
<%#Eval("[电压(V)]")%>

此时,我们会得到另一个运行时错误:

电压(V 既不是表 DataTable1 的 DataColumn 也不是 DataRelation。

表明,即使加上[]也无法解决这个特殊字段名的问题。同时字段名中如果也存在中括号,也是会出现这样的问题的。但是这样的字段名却在 GridView的自动生成列中能被正常绑定呢?问题会出现在哪里呢?分析和对比GridView的自动生成列与Eval这样的绑定语法在最终执行绑定代 码上的不同,我们可以发现,GridView的自动生成列取值并不是使用DataBinder.Eval这个方法,它内部有自己的取值方式,但是在实现上 却是大同小异的。那究竟是在哪里出现了问题呢?我们找出DataBinder类的定义:

1:[AspNetHostingPermission(SecurityAction.LinkDemand, Level=200)]
2:publicsealedclassDataBinder
3:{
4:// Fields
5:privatestaticreadonlychar[] expressionPartSeparator =newchar[] {'.'};
6:privatestaticreadonlychar[] indexExprEndChars =newchar[] {']',')'};
7:privatestaticreadonlychar[] indexExprStartChars =newchar[] {'[','('};
8: 
9:// Methods
10:publicstaticobjectEval(objectcontainer,stringexpression)
11:{
12:if(expression ==null)
13:{
14:thrownewArgumentNullException("expression");
15:}
16:expression = expression.Trim();
17:if(expression.Length == 0)
18:{
19:thrownewArgumentNullException("expression");
20:}
21:if(container ==null)
22:{
23:returnnull;
24:}
25:string[] expressionParts = expression.Split(expressionPartSeparator);
26:returnEval(container, expressionParts);
27:}
28: 
29:privatestaticobjectEval(objectcontainer,string[] expressionParts)
30:{
31:objectpropertyValue = container;
32:for(inti = 0; (i < expressionParts.Length) && (propertyValue !=null); i++)
33:{
34:stringpropName = expressionParts[i];
35:if(propName.IndexOfAny(indexExprStartChars) < 0)
36:{
37:propertyValue = GetPropertyValue(propertyValue, propName);
38:}
39:else
40:{
41:propertyValue = GetIndexedPropertyValue(propertyValue, propName);
42:}
43:}
44:returnpropertyValue;
45:}
46: 
47:publicstaticstringEval(objectcontainer,stringexpression,stringformat)
48:{
49:objectobj2 = Eval(container, expression);
50:if((obj2 ==null) || (obj2 == DBNull.Value))
51:{
52:returnstring.Empty;
53:}
54:if(string.IsNullOrEmpty(format))
55:{
56:returnobj2.ToString();
57:}
58:returnstring.Format(format, obj2);
59:}
60: 
61:publicstaticobjectGetDataItem(objectcontainer)
62:{
63:boolflag;
64:returnGetDataItem(container,outflag);
65:}
66: 
67:publicstaticobjectGetDataItem(objectcontainer,outboolfoundDataItem)
68:{
69:if(container ==null)
70:{
71:foundDataItem =false;
72:returnnull;
73:}
74:IDataItemContainer container2 = containerasIDataItemContainer;
75:if(container2 !=null)
76:{
77:foundDataItem =true;
78:returncontainer2.DataItem;
79:}
80:stringname ="DataItem";
81:PropertyInfo property = container.GetType().GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
82:if(property ==null)
83:{
84:foundDataItem =false;
85:returnnull;
86:}
87:foundDataItem =true;
88:returnproperty.GetValue(container,null);
89:}
90: 
91:publicstaticobjectGetIndexedPropertyValue(objectcontainer,stringexpr)
92:{
93:if(container ==null)
94:{
95:thrownewArgumentNullException("container");
96:}
97:if(string.IsNullOrEmpty(expr))
98:{
99:thrownewArgumentNullException("expr");
100:}
101:objectobj2 =null;
102:boolflag =false;
103:intlength = expr.IndexOfAny(indexExprStartChars);
104:intnum2 = expr.IndexOfAny(indexExprEndChars, length + 1);
105:if(((length < 0) || (num2 < 0)) || (num2 == (length + 1)))
106:{
107:thrownewArgumentException(SR.GetString("DataBinder_Invalid_Indexed_Expr",newobject[] { expr }));
108:}
109:stringpropName =null;
110:objectobj3 =null;
111:strings = expr.Substring(length + 1, (num2 - length) - 1).Trim();
112:if(length != 0)
113:{
114:propName = expr.Substring(0, length);
115:}
116:if(s.Length != 0)
117:{
118:if(((s[0] =='"') && (s[s.Length - 1] =='"')) || ((s[0] =='\'') && (s[s.Length - 1] =='\'')))
119:{
120:obj3 = s.Substring(1, s.Length - 2);
121:}
122:elseif(char.IsDigit(s[0]))
123:{
124:intnum3;
125:flag =int.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture,outnum3);
126:if(flag)
127:{
128:obj3 = num3;
129:}
130:else
131:{
132:obj3 = s;
133:}
134:}
135:else
136:{
137:obj3 = s;
138:}
139:}
140:if(obj3 ==null)
141:{
142:thrownewArgumentException(SR.GetString("DataBinder_Invalid_Indexed_Expr",newobject[] { expr }));
143:}
144:objectpropertyValue =null;
145:if((propName !=null) && (propName.Length != 0))
146:{
147:propertyValue = GetPropertyValue(container, propName);
148:}
149:else
150:{
151:propertyValue = container;
152:}
153:if(propertyValue ==null)
154:{
155:returnobj2;
156:}
157:Array array = propertyValueasArray;
158:if((array !=null) && flag)
159:{
160:returnarray.GetValue((int) obj3);
161:}
162:if((propertyValueisIList) && flag)
163:{
164:return((IList) propertyValue)[(int) obj3];
165:}
166:PropertyInfo info = propertyValue.GetType().GetProperty("Item", BindingFlags.Public | BindingFlags.Instance,null,null,newType[] { obj3.GetType() },null);
167:if(info ==null)
168:{
169:thrownewArgumentException(SR.GetString(

TAG:

引用 删除 Guest   /   2008-05-25 21:47:33
1
引用 删除 Guest   /   2008-05-13 16:20:10
5
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar