2 // System.Web.UI.DataBinder.cs
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
8 // (C) 2002 Ximian, Inc. (http://www.ximian.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System
.Collections
;
34 using System
.ComponentModel
;
35 using System
.Reflection
;
37 namespace System
.Web
.UI
{
39 public sealed class DataBinder
45 private static string FormatResult (object result
, string format
)
51 return result
.ToString ();
53 return String
.Format (format
, result
);
56 public static object Eval (object container
, string expression
)
58 if (expression
== null)
59 throw new ArgumentNullException ("expression");
61 object current
= container
;
63 while (current
!= null) {
64 int dot
= expression
.IndexOf ('.');
65 int size
= (dot
== -1) ? expression
.Length
: dot
;
66 string prop
= expression
.Substring (0, size
);
67 if (prop
.IndexOf ('[') != -1)
68 current
= GetIndexedPropertyValue (current
, prop
);
70 current
= GetPropertyValue (current
, prop
);
75 expression
= expression
.Substring (prop
.Length
+ 1);
81 public static string Eval (object container
, string expression
, string format
)
83 object result
= Eval (container
, expression
);
84 return FormatResult (result
, format
);
87 public static object GetIndexedPropertyValue (object container
, string expr
)
90 throw new ArgumentNullException ("expr");
92 int openIdx
= expr
.IndexOf ('[');
93 int closeIdx
= expr
.IndexOf (']'); // see the test case. MS ignores all after the first ]
94 if (openIdx
< 0 || closeIdx
< 0 || closeIdx
- openIdx
<= 1)
95 throw new ArgumentException (expr
+ " is not a valid indexed expression.");
97 string val
= expr
.Substring (openIdx
+ 1, closeIdx
- openIdx
- 1);
100 throw new ArgumentException (expr
+ " is not a valid indexed expression.");
102 bool is_string
= false;
103 // a quoted val means we have a string
104 if ((val
[0] == '\'' && val
[val
.Length
- 1] == '\'') ||
105 (val
[0] == '\"' && val
[val
.Length
- 1] == '\"')) {
107 val
= val
.Substring(1, val
.Length
- 2);
109 // if all chars are digits, then we have a int
110 for(int i
= 0; i
< val
.Length
; i
++)
111 if (!Char
.IsDigit(val
[i
])) {
120 intVal
= Int32
.Parse (val
);
122 throw new ArgumentException (expr
+ " is not a valid indexed expression.");
126 string property
= null;
128 property
= expr
.Substring (0, openIdx
);
129 if (property
!= null && property
!= String
.Empty
)
130 container
= GetPropertyValue (container
, property
);
133 if (container
== null)
136 if (container
is System
.Collections
.IList
) {
137 IList l
= (IList
) container
;
141 Type t
= container
.GetType ();
142 // MS does not seem to look for any other than "Item"!!!
143 object [] atts
= t
.GetCustomAttributes (typeof (DefaultMemberAttribute
), false);
144 if (atts
.Length
!= 1)
145 throw new ArgumentException (expr
+ " indexer not found.");
147 property
= ((DefaultMemberAttribute
) atts
[0]).MemberName
;
149 Type
[] argTypes
= new Type
[] { (is_string) ? typeof (string) : typeof (int) }
;
150 PropertyInfo prop
= t
.GetProperty (property
, argTypes
);
152 throw new ArgumentException (expr
+ " indexer not found.");
154 object [] args
= new object [1];
160 return prop
.GetValue (container
, args
);
163 public static string GetIndexedPropertyValue (object container
, string expr
, string format
)
165 object result
= GetIndexedPropertyValue (container
, expr
);
166 return FormatResult (result
, format
);
169 public static object GetPropertyValue (object container
, string propName
)
171 if (propName
== null)
172 throw new ArgumentNullException ("propName");
174 PropertyDescriptor prop
= TypeDescriptor
.GetProperties (container
).Find (propName
, true);
176 throw new HttpException ("Property " + propName
+ " not found in " +
177 container
.GetType ());
180 return prop
.GetValue (container
);
183 public static string GetPropertyValue (object container
, string propName
, string format
)
185 object result
= GetPropertyValue (container
, propName
);
186 return FormatResult (result
, format
);
190 public static object GetDataItem (object container
, out bool foundDataItem
)
192 foundDataItem
= false;
193 if (container
== null)
196 PropertyInfo pi
= container
.GetType ().GetProperty ("DataItem", BindingFlags
.Public
| BindingFlags
.Instance
);
200 foundDataItem
= true;
201 return pi
.GetValue (container
, null);
205 public static object GetDataItem (object container
)
208 return GetDataItem (container
, out flag
);