Parcourir la source

2007-09-20 Marek Habersack <[email protected]>

            * LoginView.cs: implemented RoleGroups support. Fixes bug
            #324633.

2007-09-20  Marek Habersack  <[email protected]>

            * TemplateControlCompiler.cs: if a member passed to
            GetExpressionFromString has a TypeConverter attribute set, try to
            use the named type converter to convert the string value into the
            target type. Fixes bug #325489.


svn path=/trunk/mcs/; revision=86092
Marek Habersack il y a 18 ans
Parent
commit
592d6443e9

+ 7 - 0
mcs/class/System.Web/System.Web.Compilation/ChangeLog

@@ -1,3 +1,10 @@
+2007-09-20  Marek Habersack  <[email protected]>
+
+	* TemplateControlCompiler.cs: if a member passed to
+	GetExpressionFromString has a TypeConverter attribute set, try to
+	use the named type converter to convert the string value into the
+	target type. Fixes bug #325489.
+
 2007-09-14  Marek Habersack  <[email protected]>
 
 	* AppResourcesCompiler.cs: use _culture and _resourceManager

+ 120 - 49
mcs/class/System.Web/System.Web.Compilation/TemplateControlCompiler.cs

@@ -1559,9 +1559,63 @@ namespace System.Web.Compilation
 			return str;
 		}
 #endif
+
+		TypeConverter GetConverterForMember (MemberInfo member)
+		{
+			TypeConverterAttribute tca = null;
+			object[] attrs;
+			
+#if NET_2_0
+			attrs = member.GetCustomAttributes (typeof (TypeConverterAttribute), true);
+			if (attrs.Length > 0)
+				tca = attrs [0] as TypeConverterAttribute;
+#else
+			attrs = member.GetCustomAttributes (true);
+			
+			foreach (object attr in attrs) {
+				tca = attr as TypeConverterAttribute;
+				
+				if (tca != null)
+					break;
+			}
+#endif
+
+			if (tca == null)
+				return null;
+
+			string typeName = tca.ConverterTypeName;
+			if (typeName == null || typeName.Length == 0)
+				return null;
+
+			Type t = null;
+			try {
+				t = Type.GetType (typeName);
+			} catch (Exception) {
+				// ignore
+			}
+
+			if (t == null)
+				return null;
+
+			return (TypeConverter) Activator.CreateInstance (t);
+		}
 		
 		CodeExpression GetExpressionFromString (Type type, string str, MemberInfo member)
 		{
+			TypeConverter cvt = GetConverterForMember (member);
+			if (cvt != null && !cvt.CanConvertFrom (typeof (string)))
+				cvt = null;
+
+			object convertedFromAttr = null;
+			bool preConverted = false;
+			if (cvt != null) {
+				convertedFromAttr = cvt.ConvertFromInvariantString (str);
+				if (convertedFromAttr != null) {
+					type = convertedFromAttr.GetType ();
+					preConverted = true;
+				}
+			}
+			
 #if NET_2_0
 			bool wasNullable = false;
 			
@@ -1571,8 +1625,11 @@ namespace System.Web.Compilation
 				wasNullable = true;
 			}
 #endif
-
+			
 			if (type == typeof (string)) {
+				if (preConverted)
+					return new CodePrimitiveExpression ((string) convertedFromAttr);
+				
 #if NET_2_0
 				object[] urlAttr = member.GetCustomAttributes (typeof (UrlPropertyAttribute), true);
 				if (urlAttr.Length != 0)
@@ -1582,6 +1639,9 @@ namespace System.Web.Compilation
 			}
 
 			if (type == typeof (bool)) {
+				if (preConverted)
+					return new CodePrimitiveExpression ((bool) convertedFromAttr);
+				
 				if (str == null || str == "" || InvariantCompareNoCase (str, "true"))
 					return new CodePrimitiveExpression (true);
 				else if (InvariantCompareNoCase (str, "false"))
@@ -1594,65 +1654,75 @@ namespace System.Web.Compilation
 					throw new ParseException (currentLocation,
 							"Value '" + str  + "' is not a valid boolean.");
 			}
-
+			
 			if (str == null)
 				return new CodePrimitiveExpression (null);
 
 			if (type.IsPrimitive)
-				return new CodePrimitiveExpression (Convert.ChangeType (str, type, CultureInfo.InvariantCulture));
+				return new CodePrimitiveExpression (
+					Convert.ChangeType (preConverted ? convertedFromAttr : str,
+							    type, CultureInfo.InvariantCulture));
 
 			if (type == typeof (string [])) {
-				string [] subs = str.Split (',');
+				string [] subs;
+
+				if (preConverted)
+					subs = (string[])convertedFromAttr;
+				else
+					subs = str.Split (',');
 				CodeArrayCreateExpression expr = new CodeArrayCreateExpression ();
 				expr.CreateType = new CodeTypeReference (typeof (string));
-				foreach (string v in subs) {
+				foreach (string v in subs)
 					expr.Initializers.Add (new CodePrimitiveExpression (v.Trim ()));
-				}
 
 				return expr;
 			}
-
-			if (type == typeof (Color)){
-				if (colorConverter == null)
-					colorConverter = TypeDescriptor.GetConverter (typeof (Color));
-
-				if (str.Trim().Length == 0) {
-					CodeTypeReferenceExpression ft = new CodeTypeReferenceExpression (typeof (Color));
-					return new CodeFieldReferenceExpression (ft, "Empty");
-				}
-				
+			
+			if (type == typeof (Color)) {
 				Color c;
-				try {
-					if (str.IndexOf (',') == -1) {
-						c = (Color) colorConverter.ConvertFromString (str);
-					} else {
-						int [] argb = new int [4];
-						argb [0] = 255;
-
-						string [] parts = str.Split (',');
-						int length = parts.Length;
-						if (length < 3)
-							throw new Exception ();
-
-						int basei = (length == 4) ? 0 : 1;
-						for (int i = length - 1; i >= 0; i--) {
-							argb [basei + i] = (int) Byte.Parse (parts [i]);
-						}
-						c = Color.FromArgb (argb [0], argb [1], argb [2], argb [3]);
-					}
-				} catch (Exception e){
-					// Hack: "LightGrey" is accepted, but only for ASP.NET, as the
-					// TypeConverter for Color fails to ConvertFromString.
-					// Hence this hack...
-					if (InvariantCompareNoCase ("LightGrey", str)) {
-						c = Color.LightGray;
-					} else {
-						throw new ParseException (currentLocation,
-							"Color " + str + " is not a valid color.", e);
+				
+				if (!preConverted) {
+					if (colorConverter == null)
+						colorConverter = TypeDescriptor.GetConverter (typeof (Color));
+				
+					if (str.Trim().Length == 0) {
+						CodeTypeReferenceExpression ft = new CodeTypeReferenceExpression (typeof (Color));
+						return new CodeFieldReferenceExpression (ft, "Empty");
 					}
-				}
 
-				if (c.IsKnownColor){
+					try {
+						if (str.IndexOf (',') == -1) {
+							c = (Color) colorConverter.ConvertFromString (str);
+						} else {
+							int [] argb = new int [4];
+							argb [0] = 255;
+
+							string [] parts = str.Split (',');
+							int length = parts.Length;
+							if (length < 3)
+								throw new Exception ();
+
+							int basei = (length == 4) ? 0 : 1;
+							for (int i = length - 1; i >= 0; i--) {
+								argb [basei + i] = (int) Byte.Parse (parts [i]);
+							}
+							c = Color.FromArgb (argb [0], argb [1], argb [2], argb [3]);
+						}
+					} catch (Exception e) {
+						// Hack: "LightGrey" is accepted, but only for ASP.NET, as the
+						// TypeConverter for Color fails to ConvertFromString.
+						// Hence this hack...
+						if (InvariantCompareNoCase ("LightGrey", str)) {
+							c = Color.LightGray;
+						} else {
+							throw new ParseException (currentLocation,
+										  "Color " + str + " is not a valid color.", e);
+						}
+					}
+				} else
+					c = (Color)convertedFromAttr;
+				
+				if (c.IsKnownColor) {
 					CodeFieldReferenceExpression expr = new CodeFieldReferenceExpression ();
 					if (c.IsSystemColor)
 						type = typeof (SystemColors);
@@ -1673,10 +1743,11 @@ namespace System.Web.Compilation
 				}
 			}
 
-			TypeConverter converter = TypeDescriptor.GetProperties (member.DeclaringType) [member.Name].Converter;
+			TypeConverter converter = preConverted ? cvt :
+				TypeDescriptor.GetProperties (member.DeclaringType) [member.Name].Converter;
 			
-			if (converter != null && converter.CanConvertFrom (typeof (string))) {
-				object value = converter.ConvertFromInvariantString (str);
+			if (preConverted || (converter != null && converter.CanConvertFrom (typeof (string)))) {
+				object value = preConverted ? convertedFromAttr : converter.ConvertFromInvariantString (str);
 
 				if (converter.CanConvertTo (typeof (InstanceDescriptor))) {
 					InstanceDescriptor idesc = (InstanceDescriptor) converter.ConvertTo (value, typeof(InstanceDescriptor));
@@ -1701,7 +1772,7 @@ namespace System.Web.Compilation
 			}
 
 			Console.WriteLine ("Unknown type: " + type + " value: " + str);
-
+			
 			return new CodePrimitiveExpression (str);
 		}
 		

+ 1 - 0
mcs/class/System.Web/System.Web.UI.WebControls/AssociatedControlConverter.cs

@@ -40,6 +40,7 @@ namespace System.Web.UI.WebControls
 
 		protected override bool FilterControl (Control control)
 		{
+			Console.WriteLine ("{0}.FilterControl ({1})", this, control);
 			if (control is WebControl)
 				return true;
 

+ 5 - 0
mcs/class/System.Web/System.Web.UI.WebControls/ChangeLog

@@ -1,3 +1,8 @@
+2007-09-20  Marek Habersack  <[email protected]>
+
+	* LoginView.cs: implemented RoleGroups support. Fixes bug
+	#324633.
+
 2007-09-19  Marek Habersack  <[email protected]>
 
 	* GridView.cs: copy attributes from GridView to the child table,

+ 36 - 7
mcs/class/System.Web/System.Web.UI.WebControls/LoginView.cs

@@ -32,6 +32,8 @@
 using System.Collections;
 using System.ComponentModel;
 using System.Security.Permissions;
+using System.Security.Principal;
+using System.Web.Security;
 
 namespace System.Web.UI.WebControls {
 
@@ -128,22 +130,49 @@ namespace System.Web.UI.WebControls {
 			}
 		}
 
-		[MonoTODO ("Handle RoleGroups")]
+		private ITemplate GetTemplateFromRoleGroup (RoleGroup rg, IPrincipal user)
+		{
+			if (user == null)
+				return null;
+			
+			foreach (string role in rg.Roles) {
+				if (user.IsInRole (role))
+					return rg.ContentTemplate;
+			}
+			
+			return null;
+		}
+		
 		protected internal override void CreateChildControls ()
 		{
 			Controls.Clear ();
 			Control c = new Control ();
+			ITemplate template = null;
+			
 			if (Page != null && Page.Request.IsAuthenticated) {
 				isAuthenticated = true;
-				if (LoggedInTemplate != null)
-					LoggedInTemplate.InstantiateIn (c);
-			}
-			else {
+
+				RoleGroupCollection rgc;
+				HttpContext ctx = HttpContext.Current;
+				IPrincipal user = ctx != null ? ctx.User : null;
+
+				if (Roles.Enabled && (rgc = RoleGroups) != null && rgc.Count > 0) {
+					foreach (RoleGroup rg in rgc) {
+						template = GetTemplateFromRoleGroup (rg, user);
+						if (template != null)
+							break;
+					}
+				}
+
+				if (template == null)
+					template = LoggedInTemplate;
+			} else {
 				isAuthenticated = false;
-				if (AnonymousTemplate != null)
-					AnonymousTemplate.InstantiateIn (c);
+				template = AnonymousTemplate;
 			}
 
+			if (template != null)
+				template.InstantiateIn (c);
 			Controls.Add (c);
 		}