MobileControlPersister.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / MIT / System / Web / UI / MobileControls / Design / MobileControlPersister.cs / 1305376 / MobileControlPersister.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.Design.MobileControls 
{ 
    using System;
    using System.Web.UI; 
    using System.Web.UI.HtmlControls;
    using System.Web.UI.MobileControls;
    using System.Web.UI.WebControls;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.ComponentModel; 
    using System.ComponentModel.Design; 
    using System.Diagnostics;
    using System.IO; 
    using System.Reflection;
    using System.Text;
    using AttributeCollection = System.Web.UI.AttributeCollection;
    using System.Globalization; 

    ///  
    ///     
    ///       Provides helper functions used in persisting Controls.
    ///     
    /// 
    [
        System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
        Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 
    ]
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] 
    internal sealed class MobileControlPersister 
    {
 
        /// 
        ///    We don't want instances of this class to be created, so mark
        ///    the constructor as private.
        ///  
        private MobileControlPersister() {
        } 
 
        /// 
        ///     
        ///       Gets the delarative type for the
        ///       specified type.
        ///    
        ///  
        /// 
        ///    The type of the declarator. 
        ///  
        /// 
        ///    The services interface exposed by the webforms designer. 
        /// 
        private static string GetDeclarativeType(Type type, IDesignerHost host) {
            Debug.Assert(host != null, "Need an IDesignerHost to create declarative type names");
            string declarativeType = null; 

            if (host != null) { 
                IWebFormReferenceManager refMgr = 
                    (IWebFormReferenceManager)host.GetService(typeof(IWebFormReferenceManager));
                Debug.Assert(refMgr != null, "Did not get back IWebFormReferenceManager service from host."); 

                if (refMgr != null) {
                    string tagPrefix = refMgr.GetTagPrefix(type);
                    if ((tagPrefix != null) && (tagPrefix.Length != 0)) { 
                        declarativeType = tagPrefix + ":" + type.Name;
                    } 
                } 
            }
 
            if (declarativeType == null)
            {
/* Begin AUI 7201  */
/* Original declarativeType = type.FullName; */ 
                if (type == typeof(System.Web.UI.MobileControls.Style))
                { 
                    declarativeType = type.Name; 
                }
                else 
                {
                    declarativeType = type.FullName;
                }
/* End AUI 7201 */ 
            }
 
            return declarativeType; 
        }
 
        /// 
        ///    
        ///       Persists a collection property.
        ///     
        /// 
        ///  
        ///    The persistance mode to use. 
        /// 
        ///  
        ///    The string writer to use.
        /// 
        /// 
        ///    The component to persist. 
        /// 
        ///  
        ///    A property descriptor for the collection property. 
        /// 
        ///  
        ///    The services interface exposed by the webforms designer.
        /// 
        private static void PersistCollectionProperty(TextWriter sw, object component, PropertyDescriptor propDesc, PersistenceMode persistMode, IDesignerHost host) {
            Debug.Assert(typeof(ICollection).IsAssignableFrom(propDesc.PropertyType), 
                "Invalid collection property : " + propDesc.Name);
 
            ICollection propValue = (ICollection)propDesc.GetValue(component); 
            if ((propValue == null) || (propValue.Count == 0))
                return; 

// Begin AUI Change #3785
// Original: sw.WriteLine();
            if (!(component is DeviceSpecific)) 
            {
                sw.WriteLine(); 
            } 
// End of Change #3785
 
            if (persistMode == PersistenceMode.InnerProperty) {
                sw.Write('<');
                sw.Write(propDesc.Name);
                sw.WriteLine('>'); 
            }
 
            IEnumerator e = propValue.GetEnumerator(); 
            while (e.MoveNext()) {
                object collItem = e.Current; 

                // Begin of AUI Change

                //string itemTypeName = GetDeclarativeType(collItem.GetType(), host); 
                string itemTypeName;
 
                // AUI : To fix Hashtable objects used in Mobile Controls, only persist the value part 
                if (collItem is DictionaryEntry)
                { 
                    collItem = ((DictionaryEntry)collItem).Value;
                }

                // AUI : First check if the control already has a Default Persist Name, 
                //       if not, use the Type as its name
 
                PersistNameAttribute pna = 
                    (PersistNameAttribute)TypeDescriptor.GetAttributes(collItem.GetType())[typeof(PersistNameAttribute)];
 
                // attribute should returns default value if it's null.
                // this is unlikely to happen, but just to be on the safe side.
                Debug.Assert (pna != null, "PersistNameAttribute returns null!");
 
                string persistName = (string)pna.Name;
 
                if (persistName != null && persistName.Length > 0) 
                {
                    itemTypeName = persistName; 
                }
/* AUI Change #3911 */
/* Original : else if (collItem is Control) */
                else if (collItem is Control || collItem.GetType() == typeof(System.Web.UI.MobileControls.Style)) 
                {
                    itemTypeName = GetDeclarativeType(collItem.GetType(), host); 
                } 
                else
                { 
                    itemTypeName = collItem.GetType().Name;
                }
                // End of AUI Change
 
                sw.Write("<");
                sw.Write(itemTypeName); 
                PersistAttributes(sw, collItem, String.Empty, null); 
                sw.Write(">");
 
                if (collItem is Control) {
                    PersistChildrenAttribute pca =
                        (PersistChildrenAttribute)TypeDescriptor.GetAttributes(collItem.GetType())[typeof(PersistChildrenAttribute)];
 
                    if (pca.Persist == true) {
                        // asurt 106696: ensure the parent control's visibility is set to true. 
                        Control parentControl = (Control)collItem; 
                        if (parentControl.HasControls())
                        { 
                            bool oldVisible = parentControl.Visible;
                            try
                            {
                                parentControl.Visible = true; 
                                PersistChildControls(sw, parentControl.Controls, host);
                            } 
                            finally 
                            {
                                parentControl.Visible = oldVisible; 
                            }
                        }
                    }
                    else { 
                        PersistInnerProperties(sw, collItem, host);
                    } 
                } 
                else {
                    PersistInnerProperties(sw, collItem, host); 
                }

                sw.Write("");
            } 
 
            if (persistMode == PersistenceMode.InnerProperty) {
                sw.Write("');
            }
        } 

        ///  
        ///     
        ///       Persists a complex property.
        ///     
        /// 
        /// 
        ///    The persistance mode to use.
        ///  
        /// 
        ///    The string writer to use. 
        ///  
        /// 
        ///    The component to persist. 
        /// 
        /// 
        ///    A property descriptor for the complex property.
        ///  
        /// 
        ///    The services interface exposed by the webforms designer. 
        ///  
        private static void PersistComplexProperty(TextWriter sw, object component, PropertyDescriptor propDesc, IDesignerHost host) {
            object propValue = propDesc.GetValue(component); 

            if (propValue == null) {
                return;
            } 

            StringWriter tagProps = new StringWriter(CultureInfo.InvariantCulture); 
            StringWriter innerProps = new StringWriter(CultureInfo.InvariantCulture); 

            PersistAttributes(tagProps, propValue, String.Empty, null); 
            PersistInnerProperties(innerProps, propValue, host);

            // the rule here is that if a complex property has all its subproperties
            // in the default state, then it itself is in the default state. 
            // When this is the case, there shouldn't be any tag properties or inner properties
            if ((tagProps.GetStringBuilder().Length != 0) || 
                (innerProps.GetStringBuilder().Length != 0)) { 

                sw.WriteLine(); 
                sw.Write('<');
                sw.Write(propDesc.Name);
                sw.Write(tagProps.ToString());
                sw.WriteLine(">"); 

                string innerPropsString = innerProps.ToString(); 
                sw.Write(innerPropsString); 
                if (innerPropsString.Length != 0) {
// Begin AUI Change #3785 
// Original: sw.WriteLine();
                    if (!propDesc.Name.Equals("DeviceSpecific"))
                    {
                        sw.WriteLine(); 
                    }
// End AUI Change #3785 
                } 

                sw.Write("');
            }
        } 

        ///  
        ///     
        ///       Persists the data bindings of the specified control using the specified
        ///       string writer. 
        ///    
        /// 
        /// 
        ///    The string writer to use. 
        /// 
        ///  
        ///    The control to use. 
        /// 
        private static void PersistDataBindings(TextWriter sw, Control control) { 
            DataBindingCollection bindings = ((IDataBindingsAccessor)control).DataBindings;
            IEnumerator bindingEnum = bindings.GetEnumerator();

            while (bindingEnum.MoveNext()) { 
                DataBinding db = (DataBinding)bindingEnum.Current;
                string persistPropName = db.PropertyName.Replace('.', '-'); 
 
                sw.Write(" ");
                sw.Write(persistPropName); 
                sw.Write("='<%# ");
                sw.Write(HttpUtility.HtmlEncode(db.Expression));
                sw.Write(" %>'");
            } 
        }
 
        ///  
        ///    
        ///       Gets a string that can persist the inner properties of a control. 
        ///    
        /// 
        /// 
        ///     
        ///       Gets a string that can persist the inner properties of a control.
        ///     
        ///  
        /// 
        ///    The component to persist. 
        /// 
        /// 
        ///    The services interface exposed by the webforms designer.
        ///  
        /// 
        ///     
        ///       A string that contains the persistable information about 
        ///       the inner properties
        ///       of the control. 
        ///    
        /// 
        internal static string PersistInnerProperties(object component, IDesignerHost host) {
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); 

            PersistInnerProperties(sw, component, host); 
            return sw.ToString(); 
        }
 
        /// 
        ///    
        ///       Persists the inner properties of the control.
        ///     
        /// 
        ///  
        ///    The string writer to use. 
        /// 
        ///  
        ///    The component to persist.
        /// 
        /// 
        ///    The services interface exposed by the webforms designer. 
        /// 
        internal static void PersistInnerProperties(TextWriter sw, object component, IDesignerHost host) { 
            PropertyDescriptorCollection propDescs = TypeDescriptor.GetProperties(component); 

            for (int i = 0; i < propDescs.Count; i++) { 
                // Only deal with inner attributes that need to be persisted
                if (propDescs[i].SerializationVisibility == DesignerSerializationVisibility.Hidden)
                    continue;
 
                PersistenceModeAttribute persistenceMode = (PersistenceModeAttribute)propDescs[i].Attributes[typeof(PersistenceModeAttribute)];
                if (persistenceMode.Mode == PersistenceMode.Attribute) { 
                    continue; 
                }
 
                if (propDescs[i].PropertyType == typeof(string)) {
                    // String based property...

                    DataBindingCollection dataBindings = null; 
                    if (component is IDataBindingsAccessor) {
                        dataBindings = ((IDataBindingsAccessor)component).DataBindings; 
                    } 
                    if (dataBindings == null || dataBindings[propDescs[i].Name] == null) {
                        PersistenceMode mode = persistenceMode.Mode; 
                        if ((mode == PersistenceMode.InnerDefaultProperty) ||
                            (mode == PersistenceMode.EncodedInnerDefaultProperty)) {
                            PersistStringProperty(sw, component, propDescs[i], mode);
                        } 
                        else {
                            Debug.Fail("Cannot persist inner string property marked with PersistenceMode.InnerProperty"); 
                        } 
                    }
                } 
                else if (typeof(ITemplate).IsAssignableFrom(propDescs[i].PropertyType)) {
                    // Template based property...
                    if (persistenceMode.Mode == PersistenceMode.InnerProperty) {
                        PersistTemplateProperty(sw, component, propDescs[i]); 
                    }
                    else { 
                        Debug.Fail("Cannot persist template property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty"); 
                    }
                } 
/* AUI change 03/21/01 */
                else if (propDescs[i].DisplayName.Equals("Templates") &&
                    component is DeviceSpecificChoice &&
                    typeof(IDictionary).IsAssignableFrom(propDescs[i].PropertyType)) { 

                    IDictionary templateCollection = (IDictionary)propDescs[i].GetValue(component); 
                    foreach (String templateName in templateCollection.Keys) { 
                        ITemplate template = (ITemplate)templateCollection[templateName];
                        PersistTemplateProperty(sw, templateName, template); 
                    }
                }
/* End of AUI change*/
                else if (typeof(ICollection).IsAssignableFrom(propDescs[i].PropertyType)) { 
                    // Collection based property...
                    if ((persistenceMode.Mode == PersistenceMode.InnerProperty) || 
                        (persistenceMode.Mode == PersistenceMode.InnerDefaultProperty)) { 
                        PersistCollectionProperty(sw, component, propDescs[i], persistenceMode.Mode, host);
                    } 
                    else {
                        Debug.Fail("Cannot persist collection property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty or PersistenceMode.InnerDefaultProperty");
                    }
                } 
                else {
                    // Other complex property... 
                    if (persistenceMode.Mode == PersistenceMode.InnerProperty) { 
                        PersistComplexProperty(sw, component, propDescs[i], host);
                    } 
                    else {
                        Debug.Fail("Cannot persist complex property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty");
                    }
                } 
            }
        } 
 
        /// 
        ///     
        ///       Persists the properties of a
        ///       string.
        ///    
        ///  
        /// 
        ///    The persistance mode to use. 
        ///  
        /// 
        ///    The string writer to use. 
        /// 
        /// 
        ///    The component to persist.
        ///  
        /// 
        ///    A property descriptor for the string properties. 
        ///  
        private static void PersistStringProperty(TextWriter sw, object component, PropertyDescriptor propDesc, PersistenceMode mode) {
            Debug.Assert(propDesc.PropertyType == typeof(string), 
                "Invalid string property : " + propDesc.Name);
            Debug.Assert((mode == PersistenceMode.InnerDefaultProperty) || (mode == PersistenceMode.EncodedInnerDefaultProperty),
                         "Inner string properties must be marked as either InnerDefaultProperty or EncodedInnerDefaultProperty");
 
            object propValue = propDesc.GetValue(component);
            if (propValue == null) { 
                return; 
            }
 
            if (mode == PersistenceMode.InnerDefaultProperty) {
                sw.Write((string)propValue);
            }
            else { 
                HttpUtility.HtmlEncode((string)propValue, sw);
            } 
        } 

        ///  
        ///    
        ///       Persists the properties of a tag.
        ///    
        ///  
        /// 
        ///    The string writer to use. 
        ///  
        /// 
        ///    The component to persist. 
        /// 
        /// 
        ///    The prefix to store.
        ///  
        /// 
        ///    A property descriptor for the tag properties. 
        ///  
        private static void PersistAttributes(TextWriter sw, object component, string prefix, PropertyDescriptor propDesc) {
            PropertyDescriptorCollection properties; 
            string persistPrefix = String.Empty;
            object value = component;

            if (propDesc != null) { 
                value = propDesc.GetValue(component);
                properties = TypeDescriptor.GetProperties(propDesc.PropertyType, 
                                                               new Attribute[] { 
                                                                   PersistenceModeAttribute.Attribute
                                                               }); 
            }
            else {
                properties = TypeDescriptor.GetProperties(component,
                                                               new Attribute[] { 
                                                                   PersistenceModeAttribute.Attribute
                                                               }); 
            } 

            if (value == null) 
                return;

            if (prefix.Length != 0)
                persistPrefix = prefix + "-"; 

            DataBindingCollection dataBindings = null; 
            bool isControl = (component is Control); 
            if ((component is IDataBindingsAccessor))
                dataBindings = ((IDataBindingsAccessor)component).DataBindings; 

            if (component is DeviceSpecificChoice)
            {
                properties = properties.Sort(new String[] {"Filter"}); 
            }
 
            for (int i = 0; i < properties.Count; i++) { 

                // Skip properties that are hidden to the serializer 
                if (properties[i].SerializationVisibility == DesignerSerializationVisibility.Hidden) {
                    continue;
                }
 
                // Skip design-time only properties such as DefaultModifiers and Name
                DesignOnlyAttribute doAttr = (DesignOnlyAttribute)properties[i].Attributes[typeof(DesignOnlyAttribute)]; 
                if ((doAttr != null) && doAttr.IsDesignOnly) { 
                    continue;
                } 

                string propName = properties[i].Name;
                Type propType = properties[i].PropertyType;
 
                object obj = properties[i].GetValue(value);
                if (obj == null) 
                    continue; 

                DefaultValueAttribute defValAttr = 
                    (DefaultValueAttribute)properties[i].Attributes[typeof(DefaultValueAttribute)];
                if ((defValAttr != null) && (obj.Equals(defValAttr.Value)))
                    continue;
 
                string persistName = propName;
/* AUI Change 3876 -- Change is taken out because of 4347 
                if (component is DeviceSpecificChoice && persistName.Equals("Xmlns")) 
                {
                    persistName = "xmlns"; 
                }
   End of Change */

                if (prefix.Length != 0) 
                    persistName = persistPrefix + persistName;
 
                PropertyDescriptorCollection subProps = null; 
                if (properties[i].SerializationVisibility == DesignerSerializationVisibility.Content) {
                    subProps = TypeDescriptor.GetProperties(propType); 
                }
                if ((subProps == null) || (subProps.Count == 0)) {
                    string persistValue = null;
 
                    //
                    DataBinding db = null; 
                    if (dataBindings != null) 
                        db = dataBindings[persistName.Replace('.', '-')];
 
                    if (db == null) {
                        if (propType.IsEnum) {
                            persistValue = Enum.Format(propType, obj, "G");
                        } 
                        else if (propType == typeof(string)) {
                            persistValue = HttpUtility.HtmlEncode(obj.ToString()); 
                        } 
                        else {
                            TypeConverter converter = properties[i].Converter; 
                            if (converter != null) {
                                persistValue = converter.ConvertToInvariantString(null, obj);
                            }
                            else { 
                                persistValue = obj.ToString();
                            } 
                            persistValue = HttpUtility.HtmlEncode(persistValue); 
                        }
 
                        if ((persistValue == null) ||
                            (persistValue.Equals("NotSet")) ||
                            (propType.IsArray && (persistValue.Length == 0)))
                            continue; 

                        sw.Write(" "); 
                        sw.Write(persistName); 
                        sw.Write("=\"");
 
                        sw.Write(persistValue);
                        sw.Write("\"");
                    }
                } 
                else {
/* 
 *  This will force all ListDictionary properties with DesignerSerializationVisibility.Content atttribute be 
 *  persisted as a series of attributes eg. . The
 *  WebControlPersistor is not able to handle this case and will return undesired results. 
 */
// AUI Change to handle DeviceSpecificChoice.Contents
                    if (obj is ListDictionary)
                    { 
                        IDictionaryEnumerator enumerator = ((ListDictionary)obj).GetEnumerator ();
                        String persistValue = null; 
 
                        while (enumerator.MoveNext ())
                        { 
                            propName = enumerator.Key as String;
                            persistValue = enumerator.Value as String;

                            Debug.Assert (propName != null, 
                                "Non-string key in DeviceSpecificChoice Contents.");
 
                            if ((propName.Length == 0) || 
                                (persistValue == null))
                                continue; 

                            sw.Write(" ");
                            sw.Write(propName);
                            sw.Write("=\""); 

                            HttpUtility.HtmlEncode((String)persistValue, sw); 
                            sw.Write("\""); 
                        }
                    } 
                    else
                    {
// End of AUI Change
 
                        // there are sub properties, don't persist this object, but
                        // recursively persist the subproperties. 
                        PersistAttributes(sw, obj, persistName, null); 
                    }
                } 
            }

            // Persist all the databindings on this control
            if (isControl) { 
                PersistDataBindings(sw, (Control)component);
 
                AttributeCollection expandos = null; 
                if (component is WebControl) {
                    expandos = ((WebControl)component).Attributes; 
                }
                else if (component is HtmlControl) {
                    expandos = ((HtmlControl)component).Attributes;
                } 
                else if (component is UserControl)
                { 
                    expandos = ((UserControl)component).Attributes; 
                }
 
                if (expandos != null) {
                    foreach (string key in expandos.Keys) {
                        sw.Write(" ");
                        sw.Write(key); 
                        sw.Write("=\"");
                        sw.Write(expandos[key]); 
                        sw.Write("\""); 
                    }
                } 
            }
        }

        ///  
        ///    
        ///       Persists a template property including the specified persistance mode, 
        ///       string writer and property descriptor. 
        ///    
        ///  
        /// 
        ///    The persistence mode to use.
        /// 
        ///  
        ///    The string writer to use.
        ///  
        ///  
        ///    The component to persist.
        ///  
        /// 
        ///    A property descriptor for the property.
        /// 
/* AUI change 03/21/01 added support for persisting Template collection */ 
        private static void PersistTemplateProperty(TextWriter sw, object component, PropertyDescriptor propDesc)
        { 
            Debug.Assert(typeof(ITemplate).IsAssignableFrom(propDesc.PropertyType), 
                "Invalid template property : " + propDesc.Name);
 
            ITemplate template = (ITemplate)propDesc.GetValue(component);
            String templateName = propDesc.Name;
            PersistTemplateProperty(sw, templateName, template);
        } 

/* AUI change 03/21/01 made the following code a seperate method */ 
        private static void PersistTemplateProperty(TextWriter sw, String templateName, ITemplate template) 
        {
            if (template == null) { 
                return;
            }

            //string templateContent = ((TemplateBuilder)template).Text; 
            string templateContent;
 
            Debug.Assert(template is TemplateBuilder, "Unexpected ITemplate implementation."); 
            if (template is TemplateBuilder) {
                templateContent = ((TemplateBuilder)template).Text; 
            }
            else {
                templateContent = String.Empty;
            } 

            sw.WriteLine(); 
            sw.Write('<'); 
// changed propDesc.Name to templateName
            sw.Write(templateName); 
            sw.Write('>');
            if (!templateContent.StartsWith("\r\n", StringComparison.Ordinal)) {
                sw.WriteLine();
            } 

            sw.Write(templateContent); 
 
            if (!templateContent.EndsWith("\r\n", StringComparison.Ordinal)) {
                sw.WriteLine(); 
            }
            sw.Write("');
        } 
 
        /// 
        ///     
        ///       Gets a string that can
        ///       persist a control.
        ///    
        ///  
        /// 
        ///     
        ///       Gets a string that can 
        ///       persist a control.
        ///     
        /// 
        /// 
        ///    The control to persist.
        ///  
        /// 
        ///     
        ///       A string that contains the persistable information about 
        ///       the control.
        ///     
        /// 
        internal static string PersistControl(Control control) {
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
 
            PersistControl(sw, control);
            return sw.ToString(); 
        } 

        ///  
        ///    
        ///       Returns a string that can
        ///       persist a control.
        ///     
        /// 
        ///  
        ///     
        ///       Returns a string that can
        ///       persist a control. 
        ///    
        /// 
        /// 
        ///    The control to persist. 
        /// 
        ///  
        ///    The services interface exposed by the webforms designer. 
        /// 
        ///  
        ///    
        ///       A string that contains the persistable information about
        ///       the control.
        ///     
        /// 
        internal static string PersistControl(Control control, IDesignerHost host) { 
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); 

            PersistControl(sw, control, host); 
            return sw.ToString();
        }

        ///  
        ///    
        ///       Persists a control using the 
        ///       specified string writer. 
        ///    
        ///  
        /// 
        ///    The string writer to use.
        /// 
        ///  
        ///    The control to persist.
        ///  
        internal static void PersistControl(TextWriter sw, Control control) { 
            if (control is LiteralControl) {
                PersistLiteralControl(sw, (LiteralControl)control); 
                return;
            }
            if (control is DesignerDataBoundLiteralControl) {
                PersistDataBoundLiteralControl(sw, (DesignerDataBoundLiteralControl)control); 
                return;
            } 
 
            ISite site = control.Site;
            if (site == null) { 
                IComponent baseComponent = (IComponent)control.Page;
                Debug.Assert(baseComponent != null, "Control does not have its Page set!");
                if (baseComponent != null) {
                    site = baseComponent.Site; 
                }
            } 
 
            IDesignerHost host = null;
            if (site != null) { 
                host = (IDesignerHost)site.GetService(typeof(IDesignerHost));
            }

            Debug.Assert(host != null, "Did not get a valid IDesignerHost reference. Expect persistence problems!"); 

            PersistControl(sw, control, host); 
        } 

        ///  
        ///    
        ///       Persists a control using the
        ///       specified string writer.
        ///     
        /// 
        ///  
        ///    The string writer to use. 
        /// 
        ///  
        ///    The control to persist.
        /// 
        /// 
        ///    The services interface exposed by the webforms designer. 
        /// 
        internal static void PersistControl(TextWriter sw, Control control, IDesignerHost host) { 
            // Literals and DataBoundLiterals must be handled specially, since they 
            // don't have a tag around them
            if (control is LiteralControl) { 
                PersistLiteralControl(sw, (LiteralControl)control);
                return;
            }
            if (control is DesignerDataBoundLiteralControl) { 
                PersistDataBoundLiteralControl(sw, (DesignerDataBoundLiteralControl)control);
                return; 
            } 

            Debug.Assert(host != null, "Did not get a valid IDesignerHost reference. Expect persistence problems!"); 

            string tagName = null;
            bool isUserControl = false;
 
            if (control is HtmlControl) {
                tagName = ((HtmlControl)control).TagName; 
            } 
            else if (control is UserControl)
            { 
                tagName = ((IUserControlDesignerAccessor)control).TagName;
                Debug.Assert((tagName != null) && (tagName.Length != 0));

                if (tagName.Length == 0) 
                {
                    // not enough information to go any further... no options, other than to throw this control out 
                    return; 
                }
 
                isUserControl = true;
            }
            else {
                tagName = GetDeclarativeType(control.GetType(), host); 
            }
 
            sw.Write('<'); 
            sw.Write(tagName);
            sw.Write(" runat=\"server\""); 
            PersistAttributes(sw, control, String.Empty, null);
            sw.Write('>');

            if (isUserControl == false) 
            {
                PersistChildrenAttribute pca = 
                    (PersistChildrenAttribute)TypeDescriptor.GetAttributes(control.GetType())[typeof(PersistChildrenAttribute)]; 

                if (pca.Persist == true) 
                {
                    if (control.HasControls())
                    {
                        // asurt 106696: Ensure parent control's visibility is true. 
                        bool oldVisible = control.Visible;
                        try 
                        { 
                            control.Visible = true;
                            PersistChildControls(sw, control.Controls, host); 
                        }
                        finally
                        {
                            control.Visible = oldVisible; 
                        }
                    } 
                } 
                else
                { 
                    // controls marked with LiteralContent == true shouldn't have
                    // children in their persisted form. They only build children
                    // collections at runtime.
 
                    PersistInnerProperties(sw, control, host);
                } 
            } 
            else
            { 
                string innerText = ((IUserControlDesignerAccessor)control).InnerText;
                if ((innerText != null) && (innerText.Length != 0))
                {
                    sw.Write(innerText); 
                }
            } 
 
            sw.Write("');
        }

        ///  
        ///    
        ///       Persists the child controls of 
        ///       the control using the specified string writer. 
        ///    
        ///  
        /// 
        ///    The string writer to use.
        /// 
        ///  
        ///    The control collection to persist.
        ///  
        ///  
        ///    The services interface exposed by the webforms designer.
        ///  
        private static void PersistChildControls(TextWriter sw, ControlCollection controls, IDesignerHost host) {
            int children = controls.Count;

            for (int i = 0; i < children; i++) { 
                PersistControl(sw, controls[i], host);
            } 
        } 

        private static void PersistDataBoundLiteralControl(TextWriter sw, DesignerDataBoundLiteralControl control) { 
            Debug.Assert(((IDataBindingsAccessor)control).HasDataBindings == true);

            DataBindingCollection bindings = ((IDataBindingsAccessor)control).DataBindings;
            DataBinding textBinding = bindings["Text"]; 
            Debug.Assert(textBinding != null, "Did not get a Text databinding from DesignerDataBoundLiteralControl");
 
            if (textBinding != null) { 
                sw.Write("<%# ");
                sw.Write(textBinding.Expression); 
                sw.Write(" %>");
            }
        }
 
        private static void PersistLiteralControl(TextWriter sw, LiteralControl control) {
            Debug.Assert(control.Text != null); 
            sw.Write(control.Text); 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.Design.MobileControls 
{ 
    using System;
    using System.Web.UI; 
    using System.Web.UI.HtmlControls;
    using System.Web.UI.MobileControls;
    using System.Web.UI.WebControls;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.ComponentModel; 
    using System.ComponentModel.Design; 
    using System.Diagnostics;
    using System.IO; 
    using System.Reflection;
    using System.Text;
    using AttributeCollection = System.Web.UI.AttributeCollection;
    using System.Globalization; 

    ///  
    ///     
    ///       Provides helper functions used in persisting Controls.
    ///     
    /// 
    [
        System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
        Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) 
    ]
    [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] 
    internal sealed class MobileControlPersister 
    {
 
        /// 
        ///    We don't want instances of this class to be created, so mark
        ///    the constructor as private.
        ///  
        private MobileControlPersister() {
        } 
 
        /// 
        ///     
        ///       Gets the delarative type for the
        ///       specified type.
        ///    
        ///  
        /// 
        ///    The type of the declarator. 
        ///  
        /// 
        ///    The services interface exposed by the webforms designer. 
        /// 
        private static string GetDeclarativeType(Type type, IDesignerHost host) {
            Debug.Assert(host != null, "Need an IDesignerHost to create declarative type names");
            string declarativeType = null; 

            if (host != null) { 
                IWebFormReferenceManager refMgr = 
                    (IWebFormReferenceManager)host.GetService(typeof(IWebFormReferenceManager));
                Debug.Assert(refMgr != null, "Did not get back IWebFormReferenceManager service from host."); 

                if (refMgr != null) {
                    string tagPrefix = refMgr.GetTagPrefix(type);
                    if ((tagPrefix != null) && (tagPrefix.Length != 0)) { 
                        declarativeType = tagPrefix + ":" + type.Name;
                    } 
                } 
            }
 
            if (declarativeType == null)
            {
/* Begin AUI 7201  */
/* Original declarativeType = type.FullName; */ 
                if (type == typeof(System.Web.UI.MobileControls.Style))
                { 
                    declarativeType = type.Name; 
                }
                else 
                {
                    declarativeType = type.FullName;
                }
/* End AUI 7201 */ 
            }
 
            return declarativeType; 
        }
 
        /// 
        ///    
        ///       Persists a collection property.
        ///     
        /// 
        ///  
        ///    The persistance mode to use. 
        /// 
        ///  
        ///    The string writer to use.
        /// 
        /// 
        ///    The component to persist. 
        /// 
        ///  
        ///    A property descriptor for the collection property. 
        /// 
        ///  
        ///    The services interface exposed by the webforms designer.
        /// 
        private static void PersistCollectionProperty(TextWriter sw, object component, PropertyDescriptor propDesc, PersistenceMode persistMode, IDesignerHost host) {
            Debug.Assert(typeof(ICollection).IsAssignableFrom(propDesc.PropertyType), 
                "Invalid collection property : " + propDesc.Name);
 
            ICollection propValue = (ICollection)propDesc.GetValue(component); 
            if ((propValue == null) || (propValue.Count == 0))
                return; 

// Begin AUI Change #3785
// Original: sw.WriteLine();
            if (!(component is DeviceSpecific)) 
            {
                sw.WriteLine(); 
            } 
// End of Change #3785
 
            if (persistMode == PersistenceMode.InnerProperty) {
                sw.Write('<');
                sw.Write(propDesc.Name);
                sw.WriteLine('>'); 
            }
 
            IEnumerator e = propValue.GetEnumerator(); 
            while (e.MoveNext()) {
                object collItem = e.Current; 

                // Begin of AUI Change

                //string itemTypeName = GetDeclarativeType(collItem.GetType(), host); 
                string itemTypeName;
 
                // AUI : To fix Hashtable objects used in Mobile Controls, only persist the value part 
                if (collItem is DictionaryEntry)
                { 
                    collItem = ((DictionaryEntry)collItem).Value;
                }

                // AUI : First check if the control already has a Default Persist Name, 
                //       if not, use the Type as its name
 
                PersistNameAttribute pna = 
                    (PersistNameAttribute)TypeDescriptor.GetAttributes(collItem.GetType())[typeof(PersistNameAttribute)];
 
                // attribute should returns default value if it's null.
                // this is unlikely to happen, but just to be on the safe side.
                Debug.Assert (pna != null, "PersistNameAttribute returns null!");
 
                string persistName = (string)pna.Name;
 
                if (persistName != null && persistName.Length > 0) 
                {
                    itemTypeName = persistName; 
                }
/* AUI Change #3911 */
/* Original : else if (collItem is Control) */
                else if (collItem is Control || collItem.GetType() == typeof(System.Web.UI.MobileControls.Style)) 
                {
                    itemTypeName = GetDeclarativeType(collItem.GetType(), host); 
                } 
                else
                { 
                    itemTypeName = collItem.GetType().Name;
                }
                // End of AUI Change
 
                sw.Write("<");
                sw.Write(itemTypeName); 
                PersistAttributes(sw, collItem, String.Empty, null); 
                sw.Write(">");
 
                if (collItem is Control) {
                    PersistChildrenAttribute pca =
                        (PersistChildrenAttribute)TypeDescriptor.GetAttributes(collItem.GetType())[typeof(PersistChildrenAttribute)];
 
                    if (pca.Persist == true) {
                        // asurt 106696: ensure the parent control's visibility is set to true. 
                        Control parentControl = (Control)collItem; 
                        if (parentControl.HasControls())
                        { 
                            bool oldVisible = parentControl.Visible;
                            try
                            {
                                parentControl.Visible = true; 
                                PersistChildControls(sw, parentControl.Controls, host);
                            } 
                            finally 
                            {
                                parentControl.Visible = oldVisible; 
                            }
                        }
                    }
                    else { 
                        PersistInnerProperties(sw, collItem, host);
                    } 
                } 
                else {
                    PersistInnerProperties(sw, collItem, host); 
                }

                sw.Write("");
            } 
 
            if (persistMode == PersistenceMode.InnerProperty) {
                sw.Write("');
            }
        } 

        ///  
        ///     
        ///       Persists a complex property.
        ///     
        /// 
        /// 
        ///    The persistance mode to use.
        ///  
        /// 
        ///    The string writer to use. 
        ///  
        /// 
        ///    The component to persist. 
        /// 
        /// 
        ///    A property descriptor for the complex property.
        ///  
        /// 
        ///    The services interface exposed by the webforms designer. 
        ///  
        private static void PersistComplexProperty(TextWriter sw, object component, PropertyDescriptor propDesc, IDesignerHost host) {
            object propValue = propDesc.GetValue(component); 

            if (propValue == null) {
                return;
            } 

            StringWriter tagProps = new StringWriter(CultureInfo.InvariantCulture); 
            StringWriter innerProps = new StringWriter(CultureInfo.InvariantCulture); 

            PersistAttributes(tagProps, propValue, String.Empty, null); 
            PersistInnerProperties(innerProps, propValue, host);

            // the rule here is that if a complex property has all its subproperties
            // in the default state, then it itself is in the default state. 
            // When this is the case, there shouldn't be any tag properties or inner properties
            if ((tagProps.GetStringBuilder().Length != 0) || 
                (innerProps.GetStringBuilder().Length != 0)) { 

                sw.WriteLine(); 
                sw.Write('<');
                sw.Write(propDesc.Name);
                sw.Write(tagProps.ToString());
                sw.WriteLine(">"); 

                string innerPropsString = innerProps.ToString(); 
                sw.Write(innerPropsString); 
                if (innerPropsString.Length != 0) {
// Begin AUI Change #3785 
// Original: sw.WriteLine();
                    if (!propDesc.Name.Equals("DeviceSpecific"))
                    {
                        sw.WriteLine(); 
                    }
// End AUI Change #3785 
                } 

                sw.Write("');
            }
        } 

        ///  
        ///     
        ///       Persists the data bindings of the specified control using the specified
        ///       string writer. 
        ///    
        /// 
        /// 
        ///    The string writer to use. 
        /// 
        ///  
        ///    The control to use. 
        /// 
        private static void PersistDataBindings(TextWriter sw, Control control) { 
            DataBindingCollection bindings = ((IDataBindingsAccessor)control).DataBindings;
            IEnumerator bindingEnum = bindings.GetEnumerator();

            while (bindingEnum.MoveNext()) { 
                DataBinding db = (DataBinding)bindingEnum.Current;
                string persistPropName = db.PropertyName.Replace('.', '-'); 
 
                sw.Write(" ");
                sw.Write(persistPropName); 
                sw.Write("='<%# ");
                sw.Write(HttpUtility.HtmlEncode(db.Expression));
                sw.Write(" %>'");
            } 
        }
 
        ///  
        ///    
        ///       Gets a string that can persist the inner properties of a control. 
        ///    
        /// 
        /// 
        ///     
        ///       Gets a string that can persist the inner properties of a control.
        ///     
        ///  
        /// 
        ///    The component to persist. 
        /// 
        /// 
        ///    The services interface exposed by the webforms designer.
        ///  
        /// 
        ///     
        ///       A string that contains the persistable information about 
        ///       the inner properties
        ///       of the control. 
        ///    
        /// 
        internal static string PersistInnerProperties(object component, IDesignerHost host) {
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); 

            PersistInnerProperties(sw, component, host); 
            return sw.ToString(); 
        }
 
        /// 
        ///    
        ///       Persists the inner properties of the control.
        ///     
        /// 
        ///  
        ///    The string writer to use. 
        /// 
        ///  
        ///    The component to persist.
        /// 
        /// 
        ///    The services interface exposed by the webforms designer. 
        /// 
        internal static void PersistInnerProperties(TextWriter sw, object component, IDesignerHost host) { 
            PropertyDescriptorCollection propDescs = TypeDescriptor.GetProperties(component); 

            for (int i = 0; i < propDescs.Count; i++) { 
                // Only deal with inner attributes that need to be persisted
                if (propDescs[i].SerializationVisibility == DesignerSerializationVisibility.Hidden)
                    continue;
 
                PersistenceModeAttribute persistenceMode = (PersistenceModeAttribute)propDescs[i].Attributes[typeof(PersistenceModeAttribute)];
                if (persistenceMode.Mode == PersistenceMode.Attribute) { 
                    continue; 
                }
 
                if (propDescs[i].PropertyType == typeof(string)) {
                    // String based property...

                    DataBindingCollection dataBindings = null; 
                    if (component is IDataBindingsAccessor) {
                        dataBindings = ((IDataBindingsAccessor)component).DataBindings; 
                    } 
                    if (dataBindings == null || dataBindings[propDescs[i].Name] == null) {
                        PersistenceMode mode = persistenceMode.Mode; 
                        if ((mode == PersistenceMode.InnerDefaultProperty) ||
                            (mode == PersistenceMode.EncodedInnerDefaultProperty)) {
                            PersistStringProperty(sw, component, propDescs[i], mode);
                        } 
                        else {
                            Debug.Fail("Cannot persist inner string property marked with PersistenceMode.InnerProperty"); 
                        } 
                    }
                } 
                else if (typeof(ITemplate).IsAssignableFrom(propDescs[i].PropertyType)) {
                    // Template based property...
                    if (persistenceMode.Mode == PersistenceMode.InnerProperty) {
                        PersistTemplateProperty(sw, component, propDescs[i]); 
                    }
                    else { 
                        Debug.Fail("Cannot persist template property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty"); 
                    }
                } 
/* AUI change 03/21/01 */
                else if (propDescs[i].DisplayName.Equals("Templates") &&
                    component is DeviceSpecificChoice &&
                    typeof(IDictionary).IsAssignableFrom(propDescs[i].PropertyType)) { 

                    IDictionary templateCollection = (IDictionary)propDescs[i].GetValue(component); 
                    foreach (String templateName in templateCollection.Keys) { 
                        ITemplate template = (ITemplate)templateCollection[templateName];
                        PersistTemplateProperty(sw, templateName, template); 
                    }
                }
/* End of AUI change*/
                else if (typeof(ICollection).IsAssignableFrom(propDescs[i].PropertyType)) { 
                    // Collection based property...
                    if ((persistenceMode.Mode == PersistenceMode.InnerProperty) || 
                        (persistenceMode.Mode == PersistenceMode.InnerDefaultProperty)) { 
                        PersistCollectionProperty(sw, component, propDescs[i], persistenceMode.Mode, host);
                    } 
                    else {
                        Debug.Fail("Cannot persist collection property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty or PersistenceMode.InnerDefaultProperty");
                    }
                } 
                else {
                    // Other complex property... 
                    if (persistenceMode.Mode == PersistenceMode.InnerProperty) { 
                        PersistComplexProperty(sw, component, propDescs[i], host);
                    } 
                    else {
                        Debug.Fail("Cannot persist complex property " + propDescs[i].Name + " not marked with PersistenceMode.InnerProperty");
                    }
                } 
            }
        } 
 
        /// 
        ///     
        ///       Persists the properties of a
        ///       string.
        ///    
        ///  
        /// 
        ///    The persistance mode to use. 
        ///  
        /// 
        ///    The string writer to use. 
        /// 
        /// 
        ///    The component to persist.
        ///  
        /// 
        ///    A property descriptor for the string properties. 
        ///  
        private static void PersistStringProperty(TextWriter sw, object component, PropertyDescriptor propDesc, PersistenceMode mode) {
            Debug.Assert(propDesc.PropertyType == typeof(string), 
                "Invalid string property : " + propDesc.Name);
            Debug.Assert((mode == PersistenceMode.InnerDefaultProperty) || (mode == PersistenceMode.EncodedInnerDefaultProperty),
                         "Inner string properties must be marked as either InnerDefaultProperty or EncodedInnerDefaultProperty");
 
            object propValue = propDesc.GetValue(component);
            if (propValue == null) { 
                return; 
            }
 
            if (mode == PersistenceMode.InnerDefaultProperty) {
                sw.Write((string)propValue);
            }
            else { 
                HttpUtility.HtmlEncode((string)propValue, sw);
            } 
        } 

        ///  
        ///    
        ///       Persists the properties of a tag.
        ///    
        ///  
        /// 
        ///    The string writer to use. 
        ///  
        /// 
        ///    The component to persist. 
        /// 
        /// 
        ///    The prefix to store.
        ///  
        /// 
        ///    A property descriptor for the tag properties. 
        ///  
        private static void PersistAttributes(TextWriter sw, object component, string prefix, PropertyDescriptor propDesc) {
            PropertyDescriptorCollection properties; 
            string persistPrefix = String.Empty;
            object value = component;

            if (propDesc != null) { 
                value = propDesc.GetValue(component);
                properties = TypeDescriptor.GetProperties(propDesc.PropertyType, 
                                                               new Attribute[] { 
                                                                   PersistenceModeAttribute.Attribute
                                                               }); 
            }
            else {
                properties = TypeDescriptor.GetProperties(component,
                                                               new Attribute[] { 
                                                                   PersistenceModeAttribute.Attribute
                                                               }); 
            } 

            if (value == null) 
                return;

            if (prefix.Length != 0)
                persistPrefix = prefix + "-"; 

            DataBindingCollection dataBindings = null; 
            bool isControl = (component is Control); 
            if ((component is IDataBindingsAccessor))
                dataBindings = ((IDataBindingsAccessor)component).DataBindings; 

            if (component is DeviceSpecificChoice)
            {
                properties = properties.Sort(new String[] {"Filter"}); 
            }
 
            for (int i = 0; i < properties.Count; i++) { 

                // Skip properties that are hidden to the serializer 
                if (properties[i].SerializationVisibility == DesignerSerializationVisibility.Hidden) {
                    continue;
                }
 
                // Skip design-time only properties such as DefaultModifiers and Name
                DesignOnlyAttribute doAttr = (DesignOnlyAttribute)properties[i].Attributes[typeof(DesignOnlyAttribute)]; 
                if ((doAttr != null) && doAttr.IsDesignOnly) { 
                    continue;
                } 

                string propName = properties[i].Name;
                Type propType = properties[i].PropertyType;
 
                object obj = properties[i].GetValue(value);
                if (obj == null) 
                    continue; 

                DefaultValueAttribute defValAttr = 
                    (DefaultValueAttribute)properties[i].Attributes[typeof(DefaultValueAttribute)];
                if ((defValAttr != null) && (obj.Equals(defValAttr.Value)))
                    continue;
 
                string persistName = propName;
/* AUI Change 3876 -- Change is taken out because of 4347 
                if (component is DeviceSpecificChoice && persistName.Equals("Xmlns")) 
                {
                    persistName = "xmlns"; 
                }
   End of Change */

                if (prefix.Length != 0) 
                    persistName = persistPrefix + persistName;
 
                PropertyDescriptorCollection subProps = null; 
                if (properties[i].SerializationVisibility == DesignerSerializationVisibility.Content) {
                    subProps = TypeDescriptor.GetProperties(propType); 
                }
                if ((subProps == null) || (subProps.Count == 0)) {
                    string persistValue = null;
 
                    //
                    DataBinding db = null; 
                    if (dataBindings != null) 
                        db = dataBindings[persistName.Replace('.', '-')];
 
                    if (db == null) {
                        if (propType.IsEnum) {
                            persistValue = Enum.Format(propType, obj, "G");
                        } 
                        else if (propType == typeof(string)) {
                            persistValue = HttpUtility.HtmlEncode(obj.ToString()); 
                        } 
                        else {
                            TypeConverter converter = properties[i].Converter; 
                            if (converter != null) {
                                persistValue = converter.ConvertToInvariantString(null, obj);
                            }
                            else { 
                                persistValue = obj.ToString();
                            } 
                            persistValue = HttpUtility.HtmlEncode(persistValue); 
                        }
 
                        if ((persistValue == null) ||
                            (persistValue.Equals("NotSet")) ||
                            (propType.IsArray && (persistValue.Length == 0)))
                            continue; 

                        sw.Write(" "); 
                        sw.Write(persistName); 
                        sw.Write("=\"");
 
                        sw.Write(persistValue);
                        sw.Write("\"");
                    }
                } 
                else {
/* 
 *  This will force all ListDictionary properties with DesignerSerializationVisibility.Content atttribute be 
 *  persisted as a series of attributes eg. . The
 *  WebControlPersistor is not able to handle this case and will return undesired results. 
 */
// AUI Change to handle DeviceSpecificChoice.Contents
                    if (obj is ListDictionary)
                    { 
                        IDictionaryEnumerator enumerator = ((ListDictionary)obj).GetEnumerator ();
                        String persistValue = null; 
 
                        while (enumerator.MoveNext ())
                        { 
                            propName = enumerator.Key as String;
                            persistValue = enumerator.Value as String;

                            Debug.Assert (propName != null, 
                                "Non-string key in DeviceSpecificChoice Contents.");
 
                            if ((propName.Length == 0) || 
                                (persistValue == null))
                                continue; 

                            sw.Write(" ");
                            sw.Write(propName);
                            sw.Write("=\""); 

                            HttpUtility.HtmlEncode((String)persistValue, sw); 
                            sw.Write("\""); 
                        }
                    } 
                    else
                    {
// End of AUI Change
 
                        // there are sub properties, don't persist this object, but
                        // recursively persist the subproperties. 
                        PersistAttributes(sw, obj, persistName, null); 
                    }
                } 
            }

            // Persist all the databindings on this control
            if (isControl) { 
                PersistDataBindings(sw, (Control)component);
 
                AttributeCollection expandos = null; 
                if (component is WebControl) {
                    expandos = ((WebControl)component).Attributes; 
                }
                else if (component is HtmlControl) {
                    expandos = ((HtmlControl)component).Attributes;
                } 
                else if (component is UserControl)
                { 
                    expandos = ((UserControl)component).Attributes; 
                }
 
                if (expandos != null) {
                    foreach (string key in expandos.Keys) {
                        sw.Write(" ");
                        sw.Write(key); 
                        sw.Write("=\"");
                        sw.Write(expandos[key]); 
                        sw.Write("\""); 
                    }
                } 
            }
        }

        ///  
        ///    
        ///       Persists a template property including the specified persistance mode, 
        ///       string writer and property descriptor. 
        ///    
        ///  
        /// 
        ///    The persistence mode to use.
        /// 
        ///  
        ///    The string writer to use.
        ///  
        ///  
        ///    The component to persist.
        ///  
        /// 
        ///    A property descriptor for the property.
        /// 
/* AUI change 03/21/01 added support for persisting Template collection */ 
        private static void PersistTemplateProperty(TextWriter sw, object component, PropertyDescriptor propDesc)
        { 
            Debug.Assert(typeof(ITemplate).IsAssignableFrom(propDesc.PropertyType), 
                "Invalid template property : " + propDesc.Name);
 
            ITemplate template = (ITemplate)propDesc.GetValue(component);
            String templateName = propDesc.Name;
            PersistTemplateProperty(sw, templateName, template);
        } 

/* AUI change 03/21/01 made the following code a seperate method */ 
        private static void PersistTemplateProperty(TextWriter sw, String templateName, ITemplate template) 
        {
            if (template == null) { 
                return;
            }

            //string templateContent = ((TemplateBuilder)template).Text; 
            string templateContent;
 
            Debug.Assert(template is TemplateBuilder, "Unexpected ITemplate implementation."); 
            if (template is TemplateBuilder) {
                templateContent = ((TemplateBuilder)template).Text; 
            }
            else {
                templateContent = String.Empty;
            } 

            sw.WriteLine(); 
            sw.Write('<'); 
// changed propDesc.Name to templateName
            sw.Write(templateName); 
            sw.Write('>');
            if (!templateContent.StartsWith("\r\n", StringComparison.Ordinal)) {
                sw.WriteLine();
            } 

            sw.Write(templateContent); 
 
            if (!templateContent.EndsWith("\r\n", StringComparison.Ordinal)) {
                sw.WriteLine(); 
            }
            sw.Write("');
        } 
 
        /// 
        ///     
        ///       Gets a string that can
        ///       persist a control.
        ///    
        ///  
        /// 
        ///     
        ///       Gets a string that can 
        ///       persist a control.
        ///     
        /// 
        /// 
        ///    The control to persist.
        ///  
        /// 
        ///     
        ///       A string that contains the persistable information about 
        ///       the control.
        ///     
        /// 
        internal static string PersistControl(Control control) {
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
 
            PersistControl(sw, control);
            return sw.ToString(); 
        } 

        ///  
        ///    
        ///       Returns a string that can
        ///       persist a control.
        ///     
        /// 
        ///  
        ///     
        ///       Returns a string that can
        ///       persist a control. 
        ///    
        /// 
        /// 
        ///    The control to persist. 
        /// 
        ///  
        ///    The services interface exposed by the webforms designer. 
        /// 
        ///  
        ///    
        ///       A string that contains the persistable information about
        ///       the control.
        ///     
        /// 
        internal static string PersistControl(Control control, IDesignerHost host) { 
            StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); 

            PersistControl(sw, control, host); 
            return sw.ToString();
        }

        ///  
        ///    
        ///       Persists a control using the 
        ///       specified string writer. 
        ///    
        ///  
        /// 
        ///    The string writer to use.
        /// 
        ///  
        ///    The control to persist.
        ///  
        internal static void PersistControl(TextWriter sw, Control control) { 
            if (control is LiteralControl) {
                PersistLiteralControl(sw, (LiteralControl)control); 
                return;
            }
            if (control is DesignerDataBoundLiteralControl) {
                PersistDataBoundLiteralControl(sw, (DesignerDataBoundLiteralControl)control); 
                return;
            } 
 
            ISite site = control.Site;
            if (site == null) { 
                IComponent baseComponent = (IComponent)control.Page;
                Debug.Assert(baseComponent != null, "Control does not have its Page set!");
                if (baseComponent != null) {
                    site = baseComponent.Site; 
                }
            } 
 
            IDesignerHost host = null;
            if (site != null) { 
                host = (IDesignerHost)site.GetService(typeof(IDesignerHost));
            }

            Debug.Assert(host != null, "Did not get a valid IDesignerHost reference. Expect persistence problems!"); 

            PersistControl(sw, control, host); 
        } 

        ///  
        ///    
        ///       Persists a control using the
        ///       specified string writer.
        ///     
        /// 
        ///  
        ///    The string writer to use. 
        /// 
        ///  
        ///    The control to persist.
        /// 
        /// 
        ///    The services interface exposed by the webforms designer. 
        /// 
        internal static void PersistControl(TextWriter sw, Control control, IDesignerHost host) { 
            // Literals and DataBoundLiterals must be handled specially, since they 
            // don't have a tag around them
            if (control is LiteralControl) { 
                PersistLiteralControl(sw, (LiteralControl)control);
                return;
            }
            if (control is DesignerDataBoundLiteralControl) { 
                PersistDataBoundLiteralControl(sw, (DesignerDataBoundLiteralControl)control);
                return; 
            } 

            Debug.Assert(host != null, "Did not get a valid IDesignerHost reference. Expect persistence problems!"); 

            string tagName = null;
            bool isUserControl = false;
 
            if (control is HtmlControl) {
                tagName = ((HtmlControl)control).TagName; 
            } 
            else if (control is UserControl)
            { 
                tagName = ((IUserControlDesignerAccessor)control).TagName;
                Debug.Assert((tagName != null) && (tagName.Length != 0));

                if (tagName.Length == 0) 
                {
                    // not enough information to go any further... no options, other than to throw this control out 
                    return; 
                }
 
                isUserControl = true;
            }
            else {
                tagName = GetDeclarativeType(control.GetType(), host); 
            }
 
            sw.Write('<'); 
            sw.Write(tagName);
            sw.Write(" runat=\"server\""); 
            PersistAttributes(sw, control, String.Empty, null);
            sw.Write('>');

            if (isUserControl == false) 
            {
                PersistChildrenAttribute pca = 
                    (PersistChildrenAttribute)TypeDescriptor.GetAttributes(control.GetType())[typeof(PersistChildrenAttribute)]; 

                if (pca.Persist == true) 
                {
                    if (control.HasControls())
                    {
                        // asurt 106696: Ensure parent control's visibility is true. 
                        bool oldVisible = control.Visible;
                        try 
                        { 
                            control.Visible = true;
                            PersistChildControls(sw, control.Controls, host); 
                        }
                        finally
                        {
                            control.Visible = oldVisible; 
                        }
                    } 
                } 
                else
                { 
                    // controls marked with LiteralContent == true shouldn't have
                    // children in their persisted form. They only build children
                    // collections at runtime.
 
                    PersistInnerProperties(sw, control, host);
                } 
            } 
            else
            { 
                string innerText = ((IUserControlDesignerAccessor)control).InnerText;
                if ((innerText != null) && (innerText.Length != 0))
                {
                    sw.Write(innerText); 
                }
            } 
 
            sw.Write("');
        }

        ///  
        ///    
        ///       Persists the child controls of 
        ///       the control using the specified string writer. 
        ///    
        ///  
        /// 
        ///    The string writer to use.
        /// 
        ///  
        ///    The control collection to persist.
        ///  
        ///  
        ///    The services interface exposed by the webforms designer.
        ///  
        private static void PersistChildControls(TextWriter sw, ControlCollection controls, IDesignerHost host) {
            int children = controls.Count;

            for (int i = 0; i < children; i++) { 
                PersistControl(sw, controls[i], host);
            } 
        } 

        private static void PersistDataBoundLiteralControl(TextWriter sw, DesignerDataBoundLiteralControl control) { 
            Debug.Assert(((IDataBindingsAccessor)control).HasDataBindings == true);

            DataBindingCollection bindings = ((IDataBindingsAccessor)control).DataBindings;
            DataBinding textBinding = bindings["Text"]; 
            Debug.Assert(textBinding != null, "Did not get a Text databinding from DesignerDataBoundLiteralControl");
 
            if (textBinding != null) { 
                sw.Write("<%# ");
                sw.Write(textBinding.Expression); 
                sw.Write(" %>");
            }
        }
 
        private static void PersistLiteralControl(TextWriter sw, LiteralControl control) {
            Debug.Assert(control.Text != null); 
            sw.Write(control.Text); 
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK