深入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: