Пример #1
0
        /// <summary>
        /// Serialize AMFX data.
        /// </summary>
        /// <exception cref="SerializationException">Error during serialization.</exception>
        private static void Serialize(XmlWriter writer, object value, SerializationContext context)
        {
            if (writer == null) throw new ArgumentNullException("writer");
            if (context == null) throw new ArgumentNullException("context");

            //A null value
            if (value == null)
            {
                WriteEmptyElement(writer, AmfxContent.Null);
                writer.Flush();
                return;
            }

            bool isDataContract;
            var type = value.GetType();
            var amfxtype = GetAmfxType(type, out isDataContract);

            //A data contract type
            if (amfxtype == AmfxContent.Object)
            {
                if (isDataContract)
                {
                    var descriptor = context.GetDescriptor(type);

                    if (descriptor == null)
                    {
                        throw new SerializationException(
                            string.Format(
                                "Unable to resolve type '{0}'. Check if type was registered within the serializer.",
                                type.FullName));
                    }
                }

                WriteDataContract(writer, value, type, context, isDataContract);
                writer.Flush();
                return;
            }

            switch (amfxtype)
            {
                case AmfxContent.Boolean:
                    WriteEmptyElement(writer, (bool)value ? AmfxContent.True : AmfxContent.False);
                    break;

                case AmfxContent.Integer:
                {
                    WriteElement(writer, amfxtype, type.IsEnum
                        ? GetEnumValue(context, type, value).ToString()
                        : value.ToString());
                    break;
                }

                case AmfxContent.Double:
                    WriteElement(writer, amfxtype, value.ToString());
                    break;

                case AmfxContent.String:
                    WriteString(writer, value.ToString(), context);
                    break;

                case AmfxContent.Date:
                    WriteDate(writer, (DateTime)value, context);
                    break;

                case AmfxContent.ByteArray:
                    WriteByteArray(writer, (byte[])value, context);
                    break;

                case AmfxContent.Xml:
                    WriteXml(writer, (XDocument)value, context);
                    break;

                case AmfxContent.Array:
                    WriteArray(writer, (object[])value, context);
                    break;

                default:
                    throw new SerializationException(string.Format("Unable to serialize type '{0}'", type.FullName));
            }

            writer.Flush();
        }
Пример #2
0
        /// <summary>
        /// Write an object.
        /// </summary>
        private static void WriteDataContract(XmlWriter writer, object graph, Type type, SerializationContext context, bool isDataContract)
        {
            var index = context.References.IndexOf(graph);

            //Write object reference
            if (index != -1)
            {
                var attributes = new Dictionary<string, string> { { AmfxContent.ReferenceId, index.ToString() } };
                WriteEmptyElement(writer, AmfxContent.Reference, attributes);
                return;
            }

            context.References.Add(new AmfReference { Reference = graph, AmfxType = AmfxContent.Object });

            Dictionary<string, object> properties;

            if (isDataContract)
            {
                var descriptor = context.GetDescriptor(type);

                if (descriptor == null)
                {
                    throw new SerializationException(
                        string.Format(
                            "Unable to resolve type '{0}'. Check if type was registered within the serializer.",
                            type.FullName));
                }

                var alias = descriptor.Alias;
                var traitsindex = context.TraitsIndex(alias);

                writer.WriteStartElement(AmfxContent.Object);

                if (!string.IsNullOrEmpty(alias))
                {
                    writer.WriteAttributeString(AmfxContent.ObjectType, alias);

                    if (traitsindex == -1)
                    {
                        var typeNameIndex = context.StringReferences.IndexOf(alias);
                        if (typeNameIndex == -1) context.StringReferences.Add(alias);
                    }
                }

                properties = DataContractHelper.GetContractProperties(graph, descriptor.PropertyMap, descriptor.FieldMap);

                //Write traits by reference
                if (context.AmfVersion == AmfVersion.Amf3 && traitsindex != -1)
                {
                    var attributes = new Dictionary<string, string> { { AmfxContent.TraitsId, traitsindex.ToString() } };
                    WriteEmptyElement(writer, AmfxContent.Traits, attributes);
                }
                //Write traits
                else
                {
                    var traits = new AmfTypeTraits { TypeName = alias, ClassMembers = properties.Keys.ToArray() };
                    context.TraitsReferences.Add(traits);

                    writer.WriteStartElement(AmfxContent.Traits);

                    foreach (var propertyName in properties.Keys)
                    {
                        WriteElement(writer, AmfxContent.String, propertyName);

                        var memberNameIndex = context.StringReferences.IndexOf(propertyName);
                        if (memberNameIndex == -1) context.StringReferences.Add(propertyName);
                    }

                    writer.WriteEndElement(); //End of traits
                }
            }
            else
            {
                var map = (IDictionary)graph;
                properties = new Dictionary<string, object>();

                foreach (var key in map.Keys)
                    properties[key.ToString()] = map[key];

                writer.WriteStartElement(AmfxContent.Object);

                writer.WriteStartElement(AmfxContent.Traits);

                foreach (var propertyName in properties.Keys)
                {
                    WriteElement(writer, AmfxContent.String, propertyName);
                    var memberNameIndex = context.StringReferences.IndexOf(propertyName);
                    if (memberNameIndex == -1) context.StringReferences.Add(propertyName);
                }

                writer.WriteEndElement(); //End of traits
            }

            foreach (var value in properties.Values)
                Serialize(writer, value, context);

            writer.WriteEndElement(); //End of object
        }