/* TODO: Migrate */ /// <summary> /// Renders the script for a given target control /// </summary> /// <param name="writer">The text writer</param> /// <param name="targetControl">The control being extended</param> private void RenderProfileBindings() { string profileComponent = null; bool startElementWritten = false; foreach (ProfilePropertyBinding profileItem in ProfileBindings) { if (profileComponent == null) { IScriptService profileService = EnsureProfileScriptService(ScriptManager.GetCurrent(Page), true); Sys.Debug.assert(profileService != null, "Failed to get ProfileScriptService"); profileComponent = profileService.ID; } if (!startElementWritten) { startElementWritten = true; writer.WriteStartElement("bindings"); } writer.WriteStartElement("binding"); Sys.Debug.assert(!string.IsNullOrEmpty(profileItem.ProfilePropertyName), "Property Name is null or empty"); writer.WriteAttributeString("dataPath", profileItem.ProfilePropertyName); writer.WriteAttributeString("dataContext", profileComponent); string propertyName = profileItem.ExtenderPropertyName; Sys.Debug.assert(!string.IsNullOrEmpty(propertyName), "Property Name is null or empty"); if (propertyName != null) { PropertyDescriptor pd = TypeDescriptor.GetProperties(props)[propertyName]; if (pd == null) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Can't find property '{0}' to bind to. Check the value of ExtenderPropertyName.", propertyName)); } ClientPropertyNameAttribute displayName = (ClientPropertyNameAttribute)pd.Attributes[typeof(ClientPropertyNameAttribute)]; if (displayName != null && !displayName.IsDefaultAttribute()) { propertyName = displayName.PropertyName; } writer.WriteAttributeString("property", propertyName); writer.WriteAttributeString("direction", "InOut"); } writer.WriteEndElement(); } if (startElementWritten) { writer.WriteEndElement(); } }
/// <summary> /// Build act-data-* options attribute on control's element /// </summary> /// <param name="targetControl"></param> /// <returns></returns> internal static string BuildDataOptionsAttribute(Control targetControl) { if (!(targetControl is IControlResolver)) { throw new Exception("JQuery control must derived from IControlResolver"); } var ctlType = targetControl.GetType(); var properties = ctlType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).ToList(); var behaviorIdProp = ctlType.GetProperty("BehaviorID"); if (behaviorIdProp != null) { properties.Add(behaviorIdProp); } var dataOptions = new List <string>(); foreach (var property in properties) { if (property.GetSetMethod(false) == null) { continue; } var propType = property.PropertyType; if (propType.IsSpecialName) { continue; } var skip = false; var customAttrs = property.GetCustomAttributes(true); IDReferencePropertyAttribute idReferencePropAttr = null; UrlPropertyAttribute urlPropAttr = null; ClientPropertyNameAttribute clientPropertyNameAttr = null; foreach (var customAttr in customAttrs) { if (customAttr is PersistenceModeAttribute) { var persistenceModeAttr = customAttr as PersistenceModeAttribute; if (persistenceModeAttr.Mode != PersistenceMode.Attribute) { skip = true; break; } } if (customAttr is BrowsableAttribute) { var browseableAttr = customAttr as BrowsableAttribute; if (!browseableAttr.Browsable) { skip = true; break; } } if (customAttr is IDReferencePropertyAttribute) { idReferencePropAttr = customAttr as IDReferencePropertyAttribute; } if (customAttr is UrlPropertyAttribute) { urlPropAttr = customAttr as UrlPropertyAttribute; } if (customAttr is ClientPropertyNameAttribute) { clientPropertyNameAttr = customAttr as ClientPropertyNameAttribute; } } if (skip) { continue; } // Determine default property value var defaultValueAttr = (DefaultValueAttribute) property.GetCustomAttributes(typeof(DefaultValueAttribute), false).FirstOrDefault(); var defaultValue = defaultValueAttr != null ? defaultValueAttr.Value : (propType.IsValueType ? Activator.CreateInstance(propType) : null); // Determine property value var value = property.GetValue(targetControl, null); if (idReferencePropAttr != null) { var control = (targetControl as IControlResolver).ResolveControl((string)value); if (control == null) { throw new Exception("Can't find control with ID '" + value + "'"); } value = control.ClientID; } else if (urlPropAttr != null) { value = targetControl.ResolveClientUrl((string)value); } // Only add non-default property values if (!object.Equals(value, defaultValue)) { var formatedValue = value.ToString(); // Encode and quotize if value is string if (propType.Equals(typeof(string))) { formatedValue = "'" + targetControl.Page.Server.HtmlEncode(formatedValue) + "'"; } var propName = clientPropertyNameAttr == null ? property.Name : clientPropertyNameAttr.PropertyName; dataOptions.Add(string.Format("{0}:{1}", CamelCaseFormat(propName), formatedValue)); } } // Returns generated data options return(string.Join(",", dataOptions.ToArray())); }
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; } }