Beispiel #1
0
        public static ControlBuilder CreateBuilderFromType(TemplateParser parser,
                                                           ControlBuilder parentBuilder,
                                                           Type type,
                                                           string tagName,
                                                           string id,
                                                           IDictionary attribs,
                                                           int line,
                                                           string sourceFileName)
        {
            Type tagType;

#if NET_2_0
            tagType = MapTagType(type);
#else
            tagType = type;
#endif
            ControlBuilder builder;
            object []      atts = tagType.GetCustomAttributes(typeof(ControlBuilderAttribute), true);
            if (atts != null && atts.Length > 0)
            {
                ControlBuilderAttribute att = (ControlBuilderAttribute)atts [0];
                builder = (ControlBuilder)Activator.CreateInstance(att.BuilderType);
            }
            else
            {
                builder = new ControlBuilder();
            }

            builder.Init(parser, parentBuilder, tagType, tagName, id, attribs);
            builder.line     = line;
            builder.fileName = sourceFileName;
            return(builder);
        }
		public void Deny_Unrestricted ()
		{
			ControlBuilderAttribute attr = new ControlBuilderAttribute (null);
			Assert.IsNull (attr.BuilderType, "BuilderType");
			Assert.IsTrue (attr.Equals (ControlBuilderAttribute.Default), "Equals");
			attr.GetHashCode ();
			Assert.IsTrue (attr.IsDefaultAttribute (), "IsDefaultAttribute");
		}
        public override bool Equals(object obj)
        {
            ControlBuilderAttribute cba = (obj as ControlBuilderAttribute);

            if (cba == null)
            {
                return(false);
            }
            return(cba.builderType == builderType);
        }
        /*
         * Create a ControlBuilder for a given tag
         */
        /// <include file='doc\ControlBuilder.uex' path='docs/doc[@for="BaseControlBuilder.CreateBuilderFromType"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public static ControlBuilder CreateBuilderFromType(TemplateParser parser,
                                                           ControlBuilder parentBuilder, Type type, string tagName,
                                                           string id, IDictionary attribs, int line, string sourceFileName)
        {
            Type builderType = null;

            // Check whether the control's class exposes a custom builder type
            ControlBuilderAttribute cba = null;

            object[] attrs = type.GetCustomAttributes(typeof(ControlBuilderAttribute), /*inherit*/ true);
            if ((attrs != null) && (attrs.Length == 1))
            {
                Debug.Assert(attrs[0] is ControlBuilderAttribute);
                cba = (ControlBuilderAttribute)attrs[0];
            }

            if (cba != null)
            {
                builderType = cba.BuilderType;
            }

            ControlBuilder builder;

            if (builderType != null)
            {
                // Make sure the type has the correct base class (ASURT 123677)
                Util.CheckAssignableType(typeof(ControlBuilder), builderType);

                // It does, so use it
                builder = (ControlBuilder)HttpRuntime.CreateNonPublicInstance(builderType);
            }
            else
            {
                // It doesn't, so use a generic one
                builder = new ControlBuilder();
            }

            // REVIEW: I'm not putting this in Init because it seems like
            // it might not be in the spirit of the method (dbau)
            builder._line           = line;
            builder._sourceFileName = sourceFileName;

            // Initialize the builder
            builder.Init(parser, parentBuilder, type, tagName, id, attribs);

            return(builder);
        }
Beispiel #5
0
        /// <summary>
        /// Construct a new blob of metadata for a single control, performing any reflection needed to determine its
        /// structure and parsing behavior.
        /// </summary>
        /// <param name="compileContext">The context in which errors should be reported.</param>
        /// <param name="tag">The complete tag for this control, as found in the markup.</param>
        /// <param name="tagRegistrations">The known list of registrations, formed from the directives in the
        /// "web.config" and any &lt;%@ Register %&gt; directives in the markup.</param>
        /// <param name="assemblies">The complete list of known pre-loaded assemblies for reflection.</param>
        /// <param name="allowedTypes">The allowable types of control that may be returned.  If the matching
        /// .NET class type for this control does not match one of these types (or is not derivable from one
        /// of these types), this constructor will throw an exception.</param>
        public ReflectedControl(ICompileContext compileContext, Tag tag, IEnumerable <TagRegistration> tagRegistrations, AssemblyLoader assemblies, IEnumerable <Type> allowedTypes)
        {
            // Decode the tag declaration.
            DecodeFullTagNameWithPrefix(tag.TagName, out TagPrefix, out TagName);

            // Find the matching C# type for that tag declaration.
            if (string.IsNullOrEmpty(TagPrefix))
            {
                TagRegistration = _htmlTagRegistration;
                ControlType     = FindMatchingHtmlControlType(tag);
            }
            else
            {
                ControlType = FindMatchingControlType(TagPrefix, TagName, tagRegistrations, assemblies, out TagRegistration);
            }
            if (ControlType == null)
            {
                throw new InvalidOperationException(string.Format("No matching type for <{0}> was found in any of the loaded assemblies.", tag.TagName));
            }

            // If we are restricted to only load certain types (such as the nested not-a-control instances inside a DataPager control),
            // check that the control we have found matches one of those types.
            if (!allowedTypes.Any(t => t.IsAssignableFrom(ControlType)))
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendFormat("Found matching type for <{0}>, but it is a {1}, not one of the {2} allowed types:\r\n",
                                           tag.TagName, ControlType.FullName, allowedTypes.Count());
                foreach (Type allowedType in allowedTypes)
                {
                    stringBuilder.AppendFormat("- {0}\r\n", allowedType.FullName);
                }
                throw new InvalidOperationException(stringBuilder.ToString());
            }

            // Extract the [ParseChildren] attribute, if it has one.
            System.Web.UI.ParseChildrenAttribute[] parseChildrenAttributes = (System.Web.UI.ParseChildrenAttribute[])ControlType.GetCustomAttributes(typeof(System.Web.UI.ParseChildrenAttribute), true);
            ParseChildrenAttribute = parseChildrenAttributes.Length == 0 ? null : parseChildrenAttributes[0];

            // Extract the [ControlBuilder] attribute, if it has one.
            System.Web.UI.ControlBuilderAttribute[] controlBuilderAttributes = (System.Web.UI.ControlBuilderAttribute[])ControlType.GetCustomAttributes(typeof(System.Web.UI.ControlBuilderAttribute), true);
            ControlBuilderAttribute = controlBuilderAttributes.Length == 0 ? null : controlBuilderAttributes[0];

            // Extract the type's properties, since their declarations control what's legal in the markup.
            ControlProperties = CollectControlProperties(compileContext, ControlType, this);

            // HtmlControls have to be handled specially, since they have [ParseChildren(true)] in many cases but
            // aren't really using it for anything.
            if (ControlType.Namespace == _htmlTagRegistration.Namespace)
            {
                ParseChildrenAttribute = new ParseChildrenAttribute(false);
            }

            // Validate the ParseChildrenAttribute, which may be broken or weird.
            if (ParseChildrenAttribute != null)
            {
                if (!string.IsNullOrEmpty(ParseChildrenAttribute.DefaultProperty))
                {
                    string propertyName = ParseChildrenAttribute.DefaultProperty.ToLower();                             // ASP.NET also ignores case on this; see internals of ControlBuilder.CreateChildBuilder() for details.
                    if (!ControlProperties.ContainsKey(propertyName))
                    {
                        throw new InvalidOperationException(string.Format("The [ParseChildren] attribute on class \"{0}\" names a default property \"{1}\" that does not exist in that class.",
                                                                          ControlType.FullName, ParseChildrenAttribute.DefaultProperty));
                    }

                    DefaultCollectionProperty = ControlProperties[propertyName];
                    if (!DefaultCollectionProperty.IsCollectionProperty)
                    {
                        throw new InvalidOperationException(string.Format("The [ParseChildren] attribute on class \"{0}\" names a default property \"{1}\" that is not a collection property.  The default property must always be a collection property.",
                                                                          ControlType.FullName, ParseChildrenAttribute.DefaultProperty));
                    }
                }
            }
        }
        /// <summary>
        /// Construct a new blob of metadata for a single control, performing any reflection needed to determine its
        /// structure and parsing behavior.
        /// </summary>
        /// <param name="compileContext">The context in which errors should be reported.</param>
        /// <param name="tag">The complete tag for this control, as found in the markup.</param>
        /// <param name="tagRegistrations">The known list of registrations, formed from the directives in the
        /// "web.config" and any &lt;%@ Register %&gt; directives in the markup.</param>
        /// <param name="assemblies">The complete list of known pre-loaded assemblies for reflection.</param>
        /// <param name="allowedTypes">The allowable types of control that may be returned.  If the matching
        /// .NET class type for this control does not match one of these types (or is not derivable from one
        /// of these types), this constructor will throw an exception.</param>
        public ReflectedControl(ICompileContext compileContext, Tag tag, IEnumerable <TagRegistration> tagRegistrations, ReferencedAssembliesContext assemblies, IEnumerable <Type> allowedTypes)
        {
            // Decode the tag declaration.
            DecodeFullTagNameWithPrefix(tag.TagName, out TagPrefix, out TagName);

            // Find the matching C# type for that tag declaration.
            if (string.IsNullOrEmpty(TagPrefix))
            {
                TagRegistration = GetHtmlTagRegistration(assemblies.SystemWebAssembly);
                ControlType     = FindMatchingHtmlControlType(tag, assemblies);
            }
            else
            {
                ControlType = FindMatchingControlType(TagPrefix, TagName, tagRegistrations, assemblies, out TagRegistration);
            }
            if (ControlType == null)
            {
                throw new InvalidOperationException(string.Format("No matching type for <{0}> was found in any of the loaded assemblies.", tag.TagName));
            }

            // If we are restricted to only load certain types (such as the nested not-a-control instances inside a DataPager control),
            // check that the control we have found matches one of those types.


            var enumerable
                = allowedTypes as Type[] ?? allowedTypes.ToArray();

            if (!enumerable.Any(t => IsSameOrSubclass(t, ControlType)))
            {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendFormat("Found matching type for <{0}>, but it is a {1}, not one of the {2} allowed types:\r\n",
                                           tag.TagName, ControlType.FullName, enumerable.Count());
                foreach (Type allowedType in enumerable)
                {
                    stringBuilder.AppendFormat("- {0}\r\n", allowedType.FullName);
                }
                throw new InvalidOperationException(stringBuilder.ToString());
            }



            // Extract the [ParseChildren] attribute, if it has one.
            var custAtts = CustomAttributeData.GetCustomAttributes(ControlType).Where(a => a.AttributeType == typeof(System.Web.UI.ParseChildrenAttribute));

            if (custAtts.Any())
            {
                var parseAtt = custAtts.First();

                if (!parseAtt.ConstructorArguments.Any())
                {
                    ParseChildrenAttribute = new ParseChildrenAttribute();
                    //public ParseChildrenAttribute();
                }
                else if (parseAtt.ConstructorArguments.Count == 1)
                {
                    //public ParseChildrenAttribute(bool childrenAsProperties);
                    //public ParseChildrenAttribute(Type childControlType);
                    if (parseAtt.ConstructorArguments[0].ArgumentType == typeof(bool))
                    {
                        bool val = (bool)parseAtt.ConstructorArguments[0].Value;
                        ParseChildrenAttribute = new ParseChildrenAttribute(val);
                    }
                    else if (parseAtt.ConstructorArguments[0].ArgumentType == typeof(Type))
                    {
                        Type val = (Type)parseAtt.ConstructorArguments[0].Value;
                        ParseChildrenAttribute = new ParseChildrenAttribute(val);
                    }
                }
                else
                {
                    //public ParseChildrenAttribute(bool childrenAsProperties, string defaultProperty);
                    bool   val            = (bool)parseAtt.ConstructorArguments[0].Value;
                    String defaultPropVal = (string)parseAtt.ConstructorArguments[1].Value;
                    ParseChildrenAttribute = new ParseChildrenAttribute(val, defaultPropVal);
                }
            }

            //System.Web.UI.ParseChildrenAttribute[] parseChildrenAttributes = (System.Web.UI.ParseChildrenAttribute[])ControlType.GetCustomAttributes(typeof(System.Web.UI.ParseChildrenAttribute), true);
            //ParseChildrenAttribute = parseChildrenAttributes.Length == 0 ? null : parseChildrenAttributes[0];

            // Extract the [ControlBuilder] attribute, if it has one.
            var controlBuilderAttsData = CustomAttributeData.GetCustomAttributes(ControlType).Where(a => a.AttributeType == typeof(System.Web.UI.ControlBuilderAttribute));

            if (controlBuilderAttsData.Any())
            {
                var controlBuilderAttData = custAtts.First();
                if (controlBuilderAttData.ConstructorArguments.Count() == 1)
                {
                    Type val = (Type)controlBuilderAttData.ConstructorArguments[0].Value;
                    ControlBuilderAttribute = new System.Web.UI.ControlBuilderAttribute(val);
                }
            }

            //System.Web.UI.ControlBuilderAttribute[] controlBuilderAttributes = (System.Web.UI.ControlBuilderAttribute[])ControlType.GetCustomAttributes(typeof(System.Web.UI.ControlBuilderAttribute), true);
            //ControlBuilderAttribute = controlBuilderAttributes.Length == 0 ? null : controlBuilderAttributes[0];

            // Extract the type's properties, since their declarations control what's legal in the markup.
            ControlProperties = CollectControlProperties(compileContext, ControlType, this);

            // HtmlControls have to be handled specially, since they have [ParseChildren(true)] in many cases but
            // aren't really using it for anything.
            if (ControlType.Namespace == GetHtmlTagRegistration(assemblies.SystemWebAssembly).Namespace)
            {
                ParseChildrenAttribute = new ParseChildrenAttribute(false);
            }

            // Validate the ParseChildrenAttribute, which may be broken or weird.
            if (ParseChildrenAttribute != null)
            {
                if (!string.IsNullOrEmpty(ParseChildrenAttribute.DefaultProperty))
                {
                    string propertyName = ParseChildrenAttribute.DefaultProperty.ToLower();   // ASP.NET also ignores case on this; see internals of ControlBuilder.CreateChildBuilder() for details.
                    if (!ControlProperties.ContainsKey(propertyName))
                    {
                        throw new InvalidOperationException(string.Format("The [ParseChildren] attribute on class \"{0}\" names a default property \"{1}\" that does not exist in that class.",
                                                                          ControlType.FullName, ParseChildrenAttribute.DefaultProperty));
                    }

                    DefaultCollectionProperty = ControlProperties[propertyName];
                    if (!DefaultCollectionProperty.IsCollectionProperty)
                    {
                        throw new InvalidOperationException(string.Format("The [ParseChildren] attribute on class \"{0}\" names a default property \"{1}\" that is not a collection property.  The default property must always be a collection property.",
                                                                          ControlType.FullName, ParseChildrenAttribute.DefaultProperty));
                    }
                }
            }
        }