/// <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(); }
/// <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 }