コード例 #1
0
        public static void DescribeComponent(object instance, IScriptComponentDescriptor descriptor, IUrlResolutionService urlResolver, IControlResolver controlResolver) {
            // validate preconditions
            if(instance == null)
                throw new ArgumentNullException("instance");
            if(descriptor == null)
                throw new ArgumentNullException("descriptor");
            if(urlResolver == null)
                urlResolver = instance as IUrlResolutionService;
            if(controlResolver == null)
                controlResolver = instance as IControlResolver;

            // describe properties
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(instance);
            foreach(PropertyDescriptor prop in properties) {
                ExtenderControlPropertyAttribute propAttr = null;
                ExtenderControlEventAttribute eventAttr = null;

                ClientPropertyNameAttribute nameAttr = null;
                IDReferencePropertyAttribute idRefAttr = null;
                UrlPropertyAttribute urlAttr = null;
                ElementReferenceAttribute elementAttr = null;
                ComponentReferenceAttribute compAttr = null;

                foreach(Attribute attr in prop.Attributes) {
                    Type attrType = attr.GetType();
                    if(attrType == typeof(ExtenderControlPropertyAttribute))
                        propAttr = attr as ExtenderControlPropertyAttribute;
                    else if(attrType == typeof(ExtenderControlEventAttribute))
                        eventAttr = attr as ExtenderControlEventAttribute;
                    else if(attrType == typeof(ClientPropertyNameAttribute))
                        nameAttr = attr as ClientPropertyNameAttribute;
                    else if(attrType == typeof(IDReferencePropertyAttribute))
                        idRefAttr = attr as IDReferencePropertyAttribute;
                    else if(attrType == typeof(UrlPropertyAttribute))
                        urlAttr = attr as UrlPropertyAttribute;
                    else if(attrType == typeof(ElementReferenceAttribute))
                        elementAttr = attr as ElementReferenceAttribute;
                    else if(attrType == typeof(ComponentReferenceAttribute))
                        compAttr = attr as ComponentReferenceAttribute;
                }

                string propertyName = prop.Name;

                // Try getting a property attribute
                if(propAttr == null || !propAttr.IsScriptProperty) {
                    // Try getting an event attribute
                    if(eventAttr == null || !eventAttr.IsScriptEvent) {
                        continue;
                    }
                }

                // attempt to rename the property/event
                if(nameAttr != null && !string.IsNullOrEmpty(nameAttr.PropertyName)) {
                    propertyName = nameAttr.PropertyName;
                }

                // determine whether to serialize the value of a property.  readOnly properties should always be serialized
                bool serialize = prop.ShouldSerializeValue(instance) || prop.IsReadOnly;
                if(serialize) {
                    // get the value of the property, skip if it is null
                    Control c = null;
                    object value = prop.GetValue(instance);
                    if(value == null) {
                        continue;
                    }

                    // convert and resolve the value
                    if(eventAttr != null && prop.PropertyType != typeof(String)) {
                        throw new InvalidOperationException("ExtenderControlEventAttribute can only be applied to a property with a PropertyType of System.String.");
                    } else {
                        if(!prop.PropertyType.IsPrimitive && !prop.PropertyType.IsEnum) {
                            // Check if we can use any of our custom converters
                            // (first do a direct lookup on the property type,
                            // but also check all of its base types if nothing
                            // was found)
                            Converter<object, string> customConverter = null;
                            if(!_customConverters.TryGetValue(prop.PropertyType, out customConverter)) {
                                foreach(KeyValuePair<Type, Converter<object, string>> pair in _customConverters) {
                                    if(prop.PropertyType.IsSubclassOf(pair.Key)) {
                                        customConverter = pair.Value;
                                        break;
                                    }
                                }
                            }

                            // Use the custom converter if found, otherwise use
                            // its current type converter
                            if(customConverter != null) {
                                value = customConverter(value);
                            } else {
                                // Determine if we should let ASP.NET AJAX handle this type of conversion, as it supports JSON serialization
                                if(propAttr != null && propAttr.UseJsonSerialization) {
                                    // Use ASP.NET JSON serialization
                                } else {
                                    // Use the property's own converter
                                    TypeConverter conv = prop.Converter;

                                    if(value.GetType() == typeof(DateTime))
                                        value = ((DateTime)value).ToString("s", CultureInfo.InvariantCulture);
                                    else
                                        value = conv.ConvertToString(null, CultureInfo.InvariantCulture, value);
                                }
                            }
                        }
                        if(idRefAttr != null && controlResolver != null) {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if(urlAttr != null && urlResolver != null) {
                            value = urlResolver.ResolveClientUrl((string)value);
                        }
                    }

                    // add the value as an appropriate description
                    if(eventAttr != null) {
                        descriptor.AddEvent(propertyName, (string)value);
                    } else if(elementAttr != null) {
                        if(c == null && controlResolver != null)
                            c = controlResolver.ResolveControl((string)value);
                        if(c != null)
                            value = c.ClientID;
                        descriptor.AddElementProperty(propertyName, (string)value);
                    } else if(compAttr != null) {
                        if(c == null && controlResolver != null)
                            c = controlResolver.ResolveControl((string)value);
                        if(c != null) {
                            ExtenderControlBase ex = c as ExtenderControlBase;
                            if(ex != null && ex.BehaviorID.Length > 0)
                                value = ex.BehaviorID;
                            else
                                value = c.ClientID;
                        }
                        descriptor.AddComponentProperty(propertyName, (string)value);
                    } else {
                        if(c != null)
                            value = c.ClientID;
                        descriptor.AddProperty(propertyName, value);
                    }
                }
            }

            // determine if we should describe methods
            foreach(MethodInfo method in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) {
                ExtenderControlMethodAttribute methAttr = (ExtenderControlMethodAttribute)Attribute.GetCustomAttribute(method, typeof(ExtenderControlMethodAttribute));
                if(methAttr == null || !methAttr.IsScriptMethod) {
                    continue;
                }

                // We only need to support emitting the callback target and registering the WebForms.js script if there is at least one valid method
                Control control = instance as Control;
                if(control != null) {
                    // Force WebForms.js
                    control.Page.ClientScript.GetCallbackEventReference(control, null, null, null);

                    // Add the callback target
                    descriptor.AddProperty("_callbackTarget", control.UniqueID);
                }
                break;
            }
        }
コード例 #2
0
        public static void DescribeComponent(object instance, IScriptComponentDescriptor descriptor, IUrlResolutionService urlResolver, IControlResolver controlResolver)
        {
            // validate preconditions
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }
            if (descriptor == null)
            {
                throw new ArgumentNullException("descriptor");
            }
            if (urlResolver == null)
            {
                urlResolver = instance as IUrlResolutionService;
            }
            if (controlResolver == null)
            {
                controlResolver = instance as IControlResolver;
            }

            // describe properties
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(instance);

            foreach (PropertyDescriptor prop in properties)
            {
                ExtenderControlPropertyAttribute propAttr  = null;
                ExtenderControlEventAttribute    eventAttr = null;

                ClientPropertyNameAttribute  nameAttr    = null;
                IDReferencePropertyAttribute idRefAttr   = null;
                UrlPropertyAttribute         urlAttr     = null;
                ElementReferenceAttribute    elementAttr = null;
                ComponentReferenceAttribute  compAttr    = null;

                foreach (Attribute attr in prop.Attributes)
                {
                    Type attrType = attr.GetType();
                    if (attrType == typeof(ExtenderControlPropertyAttribute))
                    {
                        propAttr = attr as ExtenderControlPropertyAttribute;
                    }
                    else if (attrType == typeof(ExtenderControlEventAttribute))
                    {
                        eventAttr = attr as ExtenderControlEventAttribute;
                    }
                    else if (attrType == typeof(ClientPropertyNameAttribute))
                    {
                        nameAttr = attr as ClientPropertyNameAttribute;
                    }
                    else if (attrType == typeof(IDReferencePropertyAttribute))
                    {
                        idRefAttr = attr as IDReferencePropertyAttribute;
                    }
                    else if (attrType == typeof(UrlPropertyAttribute))
                    {
                        urlAttr = attr as UrlPropertyAttribute;
                    }
                    else if (attrType == typeof(ElementReferenceAttribute))
                    {
                        elementAttr = attr as ElementReferenceAttribute;
                    }
                    else if (attrType == typeof(ComponentReferenceAttribute))
                    {
                        compAttr = attr as ComponentReferenceAttribute;
                    }
                }

                string propertyName = prop.Name;

                // Try getting a property attribute
                if (propAttr == null || !propAttr.IsScriptProperty)
                {
                    // Try getting an event attribute
                    if (eventAttr == null || !eventAttr.IsScriptEvent)
                    {
                        continue;
                    }
                }

                // attempt to rename the property/event
                if (nameAttr != null && !string.IsNullOrEmpty(nameAttr.PropertyName))
                {
                    propertyName = nameAttr.PropertyName;
                }

                // determine whether to serialize the value of a property.  readOnly properties should always be serialized
                bool serialize = prop.ShouldSerializeValue(instance) || prop.IsReadOnly;
                if (serialize)
                {
                    // get the value of the property, skip if it is null
                    Control c     = null;
                    object  value = prop.GetValue(instance);
                    if (value == null)
                    {
                        continue;
                    }

                    // convert and resolve the value
                    if (eventAttr != null && prop.PropertyType != typeof(String))
                    {
                        throw new InvalidOperationException("ExtenderControlEventAttribute can only be applied to a property with a PropertyType of System.String.");
                    }
                    else
                    {
                        if (!prop.PropertyType.IsPrimitive && !prop.PropertyType.IsEnum)
                        {
                            // Check if we can use any of our custom converters
                            // (first do a direct lookup on the property type,
                            // but also check all of its base types if nothing
                            // was found)
                            Converter <object, string> customConverter = null;
                            if (!_customConverters.TryGetValue(prop.PropertyType, out customConverter))
                            {
                                foreach (KeyValuePair <Type, Converter <object, string> > pair in _customConverters)
                                {
                                    if (prop.PropertyType.IsSubclassOf(pair.Key))
                                    {
                                        customConverter = pair.Value;
                                        break;
                                    }
                                }
                            }

                            // Use the custom converter if found, otherwise use
                            // its current type converter
                            if (customConverter != null)
                            {
                                value = customConverter(value);
                            }
                            else
                            {
                                // Determine if we should let ASP.NET AJAX handle this type of conversion, as it supports JSON serialization
                                if (propAttr != null && propAttr.UseJsonSerialization)
                                {
                                    // Use ASP.NET JSON serialization
                                }
                                else
                                {
                                    // Use the property's own converter
                                    TypeConverter conv = prop.Converter;

                                    if (value.GetType() == typeof(DateTime))
                                    {
                                        value = ((DateTime)value).ToString("s", CultureInfo.InvariantCulture);
                                    }
                                    else
                                    {
                                        value = conv.ConvertToString(null, CultureInfo.InvariantCulture, value);
                                    }
                                }
                            }
                        }
                        if (idRefAttr != null && controlResolver != null)
                        {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if (urlAttr != null && urlResolver != null)
                        {
                            value = urlResolver.ResolveClientUrl((string)value);
                        }
                    }

                    // add the value as an appropriate description
                    if (eventAttr != null)
                    {
                        descriptor.AddEvent(propertyName, (string)value);
                    }
                    else if (elementAttr != null)
                    {
                        if (c == null && controlResolver != null)
                        {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if (c != null)
                        {
                            value = c.ClientID;
                        }
                        descriptor.AddElementProperty(propertyName, (string)value);
                    }
                    else if (compAttr != null)
                    {
                        if (c == null && controlResolver != null)
                        {
                            c = controlResolver.ResolveControl((string)value);
                        }
                        if (c != null)
                        {
                            ExtenderControlBase ex = c as ExtenderControlBase;
                            if (ex != null && ex.BehaviorID.Length > 0)
                            {
                                value = ex.BehaviorID;
                            }
                            else
                            {
                                value = c.ClientID;
                            }
                        }
                        descriptor.AddComponentProperty(propertyName, (string)value);
                    }
                    else
                    {
                        if (c != null)
                        {
                            value = c.ClientID;
                        }
                        descriptor.AddProperty(propertyName, value);
                    }
                }
            }

            // determine if we should describe methods
            foreach (MethodInfo method in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
            {
                ExtenderControlMethodAttribute methAttr = (ExtenderControlMethodAttribute)Attribute.GetCustomAttribute(method, typeof(ExtenderControlMethodAttribute));
                if (methAttr == null || !methAttr.IsScriptMethod)
                {
                    continue;
                }

                // We only need to support emitting the callback target and registering the WebForms.js script if there is at least one valid method
                Control control = instance as Control;
                if (control != null)
                {
                    // Force WebForms.js
                    control.Page.ClientScript.GetCallbackEventReference(control, null, null, null);

                    // Add the callback target
                    descriptor.AddProperty("_callbackTarget", control.UniqueID);
                }
                break;
            }
        }