示例#1
0
        /// <summary>
        /// Get a ReflectedControl for the given markup tag, if one exists, restricting the search
        /// to just class types that are included in the allowed-types list (or types that inherit from them).
        /// </summary>
        /// <param name="compileContext">The context in which errors should be reported.</param>
        /// <param name="tag">The complete markup tag to search for.</param>
        /// <param name="allowedTypes">The allowed types that can be returned.  If you want to accept
        /// all possible types, pass in a list containing just typeof(object).</param>
        /// <returns>The found control type.</returns>
        public ReflectedControl GetControl(ICompileContext compileContext, Tag tag, IEnumerable <Type> allowedTypes)
        {
            bool isNormalServerControl = tag.TagName.Contains(":");

            if (isNormalServerControl && _reflectedControls.ContainsKey(tag.TagName))
            {
                return(_reflectedControls[tag.TagName]);
            }

            ReflectedControl reflectedControl = new ReflectedControl(compileContext, tag, _tagRegistrations, _assemblies, allowedTypes);

            if (isNormalServerControl && tag.TagName.Contains(":"))
            {
                _reflectedControls[tag.TagName] = reflectedControl;
            }

            return(reflectedControl);
        }
示例#2
0
        /// <summary>
        /// Construct an instance of a ReflectedControlProperty, given the control for this property and the
        /// pre-reflected PropertyInfo for the property in question.
        /// </summary>
        /// <param name="reflectedControl">The control that owns this property.</param>
        /// <param name="propertyInfo">The pre-reflected PropertyInfo for this property.</param>
        public ReflectedControlProperty(ReflectedControl reflectedControl, PropertyInfo propertyInfo)
        {
            ReflectedControl = reflectedControl;
            PropertyInfo     = propertyInfo;


            var custAtts = CustomAttributeData.GetCustomAttributes(PropertyInfo).Where(a => a.AttributeType == typeof(System.Web.UI.PersistenceModeAttribute));

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

                // public PersistenceModeAttribute(PersistenceMode mode);
                if (parseAtt.ConstructorArguments.Count == 1)
                {
                    PersistenceMode val = (PersistenceMode)parseAtt.ConstructorArguments[0].Value;
                    PersistenceModeAttribute = new System.Web.UI.PersistenceModeAttribute(val);
                    //public ParseChildrenAttribute();
                }
            }
            else
            {
                PersistenceModeAttribute = null;
            }



            //System.Web.UI.PersistenceModeAttribute[] persistenceModeAttributes = (System.Web.UI.PersistenceModeAttribute[])propertyInfo.GetCustomAttributes(typeof(System.Web.UI.PersistenceModeAttribute), true);
            //PersistenceModeAttribute = persistenceModeAttributes.Length == 0 ? null : persistenceModeAttributes[0];

            IsTemplateProperty   = typeof(System.Web.UI.ITemplate).IsAssignableFrom(PropertyInfo.PropertyType);
            IsCollectionProperty = typeof(IEnumerable).IsAssignableFrom(PropertyInfo.PropertyType) && !IsTemplateProperty;

            if (IsTemplateProperty)
            {
                var custTemplateInstanceAtts = CustomAttributeData.GetCustomAttributes(PropertyInfo).Where(a => a.AttributeType == typeof(System.Web.UI.TemplateInstanceAttribute));
                if (custTemplateInstanceAtts.Any())
                {
                    var parseAtt = custTemplateInstanceAtts.First();

                    // public TemplateInstanceAttribute(TemplateInstance instances);
                    if (parseAtt.ConstructorArguments.Count == 1)
                    {
                        TemplateInstance val = (TemplateInstance)parseAtt.ConstructorArguments[0].Value;
                        TemplateInstanceAttribute = new System.Web.UI.TemplateInstanceAttribute(val);
                        //public ParseChildrenAttribute();
                    }
                }
                else
                {
                    TemplateInstanceAttribute = null;
                }


                //System.Web.UI.TemplateInstanceAttribute[] templateInstanceAttributes = (System.Web.UI.TemplateInstanceAttribute[])propertyInfo.GetCustomAttributes(typeof(System.Web.UI.TemplateInstanceAttribute), true);
                //TemplateInstanceAttribute = templateInstanceAttributes.Length == 0 ? null : templateInstanceAttributes[0];


                var custTemplateContainerAtts = CustomAttributeData.GetCustomAttributes(PropertyInfo).Where(a => a.AttributeType == typeof(System.Web.UI.TemplateContainerAttribute));
                if (custTemplateContainerAtts.Any())
                {
                    var parseAtt = custTemplateContainerAtts.First();


                    if (parseAtt.ConstructorArguments.Count == 1)
                    {
                        // public TemplateContainerAttribute(Type containerType);
                        Type val = (Type)parseAtt.ConstructorArguments[0].Value;
                        TemplateContainerAttribute = new System.Web.UI.TemplateContainerAttribute(val);
                    }
                    else if (parseAtt.ConstructorArguments.Count == 2)
                    {
                        // public TemplateContainerAttribute(Type containerType, BindingDirection bindingDirection);
                        Type             val = (Type)parseAtt.ConstructorArguments[0].Value;
                        BindingDirection dir = (BindingDirection)parseAtt.ConstructorArguments[1].Value;
                        TemplateContainerAttribute = new System.Web.UI.TemplateContainerAttribute(val, dir);
                    }
                }
                else
                {
                    TemplateContainerAttribute = null;
                }

                //System.Web.UI.TemplateContainerAttribute[] templateContainerAttributes = (System.Web.UI.TemplateContainerAttribute[])propertyInfo.GetCustomAttributes(typeof(System.Web.UI.TemplateContainerAttribute), true);
                //TemplateContainerAttribute = templateContainerAttributes.Length == 0 ? null : templateContainerAttributes[0];
            }
            else if (IsCollectionProperty)
            {
                CollectionItemTypes = GetCollectionItemTypes(PropertyInfo.PropertyType);
            }
        }
        ///// <summary>
        ///// Given a tag with runat="server" on an HTML element, find a suitable HTML server control for it.
        ///// </summary>
        ///// <param name="tag">The tag to find an HTML server control for.</param>
        ///// <returns>The matching HTML server control.</returns>
        //private static Type FindMatchingHtmlControlType(Tag tag)
        //{


        //    switch (tag.TagName)
        //    {
        //        case "a": return typeof(System.Web.UI.HtmlControls.HtmlAnchor);
        //        case "button": return typeof(System.Web.UI.HtmlControls.HtmlButton);
        //        case "form": return typeof(System.Web.UI.HtmlControls.HtmlForm);
        //        case "head": return typeof(System.Web.UI.HtmlControls.HtmlHead);
        //        case "img": return typeof(System.Web.UI.HtmlControls.HtmlImage);
        //        case "link": return typeof(System.Web.UI.HtmlControls.HtmlLink);
        //        case "meta": return typeof(System.Web.UI.HtmlControls.HtmlMeta);
        //        case "select": return typeof(System.Web.UI.HtmlControls.HtmlSelect);
        //        case "table": return typeof(System.Web.UI.HtmlControls.HtmlTable);
        //        case "td": return typeof(System.Web.UI.HtmlControls.HtmlTableCell);
        //        case "th": return typeof(System.Web.UI.HtmlControls.HtmlTableCell);
        //        case "tr": return typeof(System.Web.UI.HtmlControls.HtmlTableRow);
        //        case "textarea": return typeof(System.Web.UI.HtmlControls.HtmlTextArea);
        //        case "title": return typeof(System.Web.UI.HtmlControls.HtmlTitle);

        //        case "input":
        //            string type = tag["type"];
        //            if (!string.IsNullOrEmpty(type))
        //            {
        //                switch (type.ToLower())
        //                {
        //                    case "button": return typeof(System.Web.UI.HtmlControls.HtmlInputButton);
        //                    case "checkbox": return typeof(System.Web.UI.HtmlControls.HtmlInputCheckBox);
        //                    case "file": return typeof(System.Web.UI.HtmlControls.HtmlInputFile);
        //                    case "hidden": return typeof(System.Web.UI.HtmlControls.HtmlInputHidden);
        //                    case "image": return typeof(System.Web.UI.HtmlControls.HtmlInputImage);
        //                    case "password": return typeof(System.Web.UI.HtmlControls.HtmlInputPassword);
        //                    case "radio": return typeof(System.Web.UI.HtmlControls.HtmlInputRadioButton);
        //                    case "reset": return typeof(System.Web.UI.HtmlControls.HtmlInputReset);
        //                    case "submit": return typeof(System.Web.UI.HtmlControls.HtmlInputSubmit);
        //                    case "text": return typeof(System.Web.UI.HtmlControls.HtmlInputText);
        //                }
        //            }
        //            return typeof(System.Web.UI.HtmlControls.HtmlGenericControl);

        //        default:
        //            return typeof(System.Web.UI.HtmlControls.HtmlGenericControl);
        //    }
        //}

        /// <summary>
        /// Find all of the properties for this control, via reflection.
        /// </summary>
        /// <returns>A dictionary of properties for the given control type.</returns>
        private static Dictionary <string, ReflectedControlProperty> CollectControlProperties(ICompileContext compileContext, Type controlType, ReflectedControl reflectedControl)
        {
            Dictionary <string, ReflectedControlProperty> controlProperties = new Dictionary <string, ReflectedControlProperty>();

            // We have to include NonPublic properties, since internal, public, or protected properties can all be
            // legally referenced from the markup.
            PropertyInfo[] propertyInfos = controlType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                // Find out what kind of getters and setter this property has.  If it has none, or both of them are private, we can't work with it.
                MethodInfo setMethodInfo      = propertyInfo.GetSetMethod(true);
                MethodInfo getMethodInfo      = propertyInfo.GetGetMethod(true);
                bool       hasUsableSetMethod = (setMethodInfo != null && (setMethodInfo.IsPublic || setMethodInfo.IsFamilyOrAssembly));
                bool       hasUsableGetMethod = (getMethodInfo != null && (getMethodInfo.IsPublic || getMethodInfo.IsFamilyOrAssembly));
                if (!hasUsableSetMethod && !hasUsableGetMethod)
                {
                    continue;
                }

                // We have a public-ish setter.  So add a ReflectedControlProperty instance for this property,
                // since it could be accessible from markup.
                ReflectedControlProperty reflectedControlProperty = new ReflectedControlProperty(reflectedControl, propertyInfo);

                // Add it to the set of known properties for this control.  We don't have the ability to support
                // case differentiation on property names, and ASP.NET will bork if anybody tries.  So if you have
                // multiple properties with the same name that differ only by case, that's just bad mojo, and you
                // should change your controls so that isn't true anymore.
                string lowerName = propertyInfo.Name.ToLower();
                if (controlProperties.ContainsKey(lowerName))
                {
                    ReflectedControlProperty previousProperty  = controlProperties[lowerName];
                    Type         previousPropertyDeclaringType = previousProperty.PropertyInfo.DeclaringType;
                    PropertyInfo baseProperty = previousPropertyDeclaringType.BaseType.GetProperty(lowerName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
                    if (baseProperty == null)
                    {
                        compileContext.Warning(string.Format("The server control \"{0}\" contains multiple properties named \"{1}\".  Keeping the {2} declaration and discarding the {3} declaration.",
                                                             controlType.FullName, propertyInfo.Name, controlProperties[lowerName].PropertyInfo.PropertyType.FullName, propertyInfo.PropertyType.FullName));
                    }
                    else
                    {
                        // This appears to be a case of a child class's property shadowing a parent class's property.
                        // That's a safe thing, or should be, so we don't throw out a warning when it happens.
                        compileContext.Verbose(string.Format("The server control \"{0}\" contains multiple properties named \"{1}\" (but one comes from a parent class, so the 'new' keyword was probably involved, and this should be safe).  Keeping the {2} declaration and discarding the {3} declaration.",
                                                             controlType.FullName, propertyInfo.Name, controlProperties[lowerName].PropertyInfo.PropertyType.FullName, propertyInfo.PropertyType.FullName));
                    }
                    continue;
                }
                controlProperties.Add(lowerName, reflectedControlProperty);
            }

            return(controlProperties);
        }