Ejemplo n.º 1
0
        /// <summary>
        /// Check to see if the object has been serialized before. If it has, then make sure
        /// that the reference information for it is added.
        /// </summary>
        /// <remarks>This routine has the overloaded</remarks>
        /// <param name="_object">The object that's being serialized</param>
        /// <param name="_elementForObject">
        /// The element that the object is being serialized to
        /// </param>
        /// <returns>TRUE if the object is a duplicate, FALSE if it is a "new" object</returns>
        private bool HandleDuplicateReferences(object _object, XmlElement _elementForObject)
        {
            var oType = _object.GetType();

            if (oType.IsPrimitive)
            {
                return(false);
            }
            if (oType == TYPEOF_STRING && !m_context.DuplicateStringsCanBeReferredTo)
            {
                return(false);
            }
            if (oType.IsEnum)
            {
                return(false);
            }

            if (m_references.TryGetValue(_object, out var refElem)) // The object was serialized already
            {
                if (ReferenceEquals(_elementForObject, refElem))    // If this IS the referenced element, then skip it
                {
                    return(false);
                }

                var refId = XmlExtensions.GetAttributeValue(refElem, m_context.ReferenceIdAttributeName);
                if (refId == null) // The object that was serialized doesn't have its RefID set yet
                {
                    refId = m_refId.ToString();
                    XmlExtensions.AddAttribute(refElem, m_context.ReferenceIdAttributeName, refId);
                    m_refId++;
                }
                // Add the "ReferTo" attribute to the xml
                XmlExtensions.AddAttribute(_elementForObject, m_context.ReferToAttributeName, refId);

                // Remove a "Type" attribute (if it exists) because this becomes redundant with
                // the presence of RefTo
                XmlExtensions.RemoveAttribute(_elementForObject, m_context.TypeAttributeName);

                return(true);
            }

            m_references.Add(_object, _elementForObject);
            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This "different" serializer handles Properties, not Fields, and conforms to the
        /// conventions found in Microsoft's Entity Framework
        /// </summary>
        /// <param name="_object"></param>
        /// <param name="_useType"></param>
        /// <param name="_elementForObject"></param>
        private void SerializeUsingEntitySemantics(object _object, Type _useType, XmlElement _elementForObject)
        {
            XmlExtensions.AddAttribute(_elementForObject, m_context.UseEntitySemanticsAttributeName, "1");

            // Gets (cached) type data pertinent to serializing an Entity
            var typeData = CEntityTypeData.GetTypeData(_useType);

            // First serialize all the "single" properties- No collections
            for (var i = 0; i < typeData.NonCollectionProperties.Length; i++)
            {
                var prop = typeData.NonCollectionProperties[i];

                var val = prop.GetValue(_object);
                FrameworkSerialize(prop.Name, val, _elementForObject, prop.PropertyType);
            }

            // Now serialize all the collections which are presumed to be the "Many" in a
            // Many-To-One relationship. The exact Type of the collection in this object is
            // irrelevant because the collection should merely implement ICollection for the
            // deserialization, and the deserialization target class should determine the exact
            // collection Type, or if its an Interface the PreferredCollectionType on the
            // AUseEntitySemantics attribute will dictate what to create.
            for (var i = 0; i < typeData.CollectionProperties.Length; i++)
            {
                var col = typeData.CollectionProperties[i];
                var collectionElement = XmlExtensions.AddElement(_elementForObject, col.Name);

                Type elementType = null; // set if the PropertyType is a generic collection
                if (col.PropertyType.IsGenericType)
                {
                    elementType = col.PropertyType.GetGenericArguments()[0];
                }

                foreach (var item in col.GetValue(_object) as System.Collections.IEnumerable)
                {
                    FrameworkSerialize(m_context.ArrayElementName, item, collectionElement, elementType);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Create an XmlElement for an object. Do not populate the new element.
        /// </summary>
        /// <remarks>
        /// FieldRenamers are NOT called at this level- the caller of this method needs to
        /// handle all field renaming
        /// </remarks>
        /// <param name="_elementName">
        /// The name that should be assigned to the newly created element
        /// </param>
        /// <param name="_expectedType">
        /// The expected type of the object. Used to decide whether or not to add explicit Type
        /// data
        /// </param>
        /// <param name="_object">The object that is being serialized</param>
        /// <param name="_parentNode">The XML node that the new node will be a child of</param>
        /// <returns>An XmlElement with some basic attributes for an object</returns>
        private XmlElement CreateElementForValue(string _elementName, object _object, XmlNode _parentNode, Type _expectedType)
        {
            var fixedElementName = FixMemberName(_elementName);
            var elem             = XmlExtensions.CreateElement(_parentNode, fixedElementName);

            if (_object == null)
            {
                XmlExtensions.AddAttribute(elem, m_context.NullAttributeName, m_context.NullAttributeValue);
            }
            else
            {
                var oType = _object.GetType();
                oType = CEntityTypeData.StripProxyType(oType);

                if (_expectedType != oType) // There must be a Type attribute added
                {
                    XmlExtensions.AddAttribute(elem, m_context.TypeAttributeName, oType.AssemblyQualifiedName);
                }
            }

            return(elem);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Use this method when an Array field needs to be added to the XML serialization
        /// </summary>
        /// <remarks>
        /// For element types that are primitives and strings, build a comma-separated list of
        /// values that should end up taking less space. For all other element types, create
        /// child-elements for each array element.
        /// </remarks>
        /// <param name="_array">The array to add to the XML Element</param>
        /// <param name="_elementToAddTo">The XML Element that is to contain the array</param>
        private void AddArrayToXml(Array _array, XmlElement _elementToAddTo)
        {
            if (_array.Rank != 1)
            {
                AddMultiDimensionalArray(_array, _elementToAddTo);
                return;
            }

            var arrayType   = _array.GetType();
            var elementType = arrayType.GetElementType();

            var count      = _array.Length;
            var lowerBound = _array.GetLowerBound(0);
            var upperBound = _array.GetUpperBound(0);

            XmlExtensions.AddAttribute(_elementToAddTo, m_context.ArrayAttributeName, count);
            if (lowerBound != 0)
            {
                XmlExtensions.AddAttribute(_elementToAddTo, m_context.ArrayLowerBoundAttribute, lowerBound);
            }

            if (elementType.IsPrimitive && !m_context.AllArraysHaveExplicitElements)
            {
                // Helper doesn't care what the element type is, so we screen it first by making
                // sure its a primitive.
                _elementToAddTo.InnerText = Lib.ConvertArrayToString(_array);
            }
            else if (elementType == TYPEOF_STRING && !m_context.AllArraysHaveExplicitElements)
            {
                // Strings could theoretically be treated with the same helper used above IF
                // they never contained commas.
                var str = ConvertStringArrayToCommaList(_array);
                _elementToAddTo.InnerText = str;
            }
            else
            {
                var skipped     = false;
                var elementName = GetNameForCollectionElement();

                for (var i = lowerBound; i <= upperBound; i++)
                {
                    var arrayElementValue = _array.GetValue(i);

                    if (arrayElementValue == null && m_context.RemoveNullValuesFromXml)
                    {
                        skipped = true;
                    }
                    else
                    {
                        var elem = FrameworkSerialize(elementName, arrayElementValue, _elementToAddTo, elementType);

                        if (m_context.ArrayElementsIncludeIndicies || skipped)
                        {
                            XmlExtensions.AddAttribute(elem, m_context.ArrayIndexAttributeName, i);
                        }

                        skipped = false;
                    }
                }
            }
        }