public void Serialize(Type type, object graph)
        {
            if (graph == null)
            {
                writer.WriteAttributeString("nil", XmlSchema.InstanceNamespace, "true");
            }
            else
            {
                Type actualType = graph.GetType();

                SerializationMap map = types.FindUserMap(actualType);
                // For some collection types, the actual type does not matter. So get nominal serialization type instead.
                // (The code below also covers the lines above, but I don't remove above lines to avoid extra search cost.)
                if (map == null)
                {
                    actualType = types.GetSerializedType(actualType);
                    map        = types.FindUserMap(actualType);
                }
                // If it is still unknown, then register it.
                if (map == null)
                {
                    types.Add(actualType);
                    map = types.FindUserMap(actualType);
                }

                if (actualType != type && (map == null || map.OutputXsiType))
                {
                    QName  qname = types.GetXmlName(actualType);
                    string name  = qname.Name;
                    string ns    = qname.Namespace;
                    if (qname == QName.Empty)
                    {
                        name = XmlConvert.EncodeLocalName(actualType.Name);
                        ns   = KnownTypeCollection.DefaultClrNamespaceBase + actualType.Namespace;
                    }
                    else if (qname.Namespace == KnownTypeCollection.MSSimpleNamespace)
                    {
                        ns = XmlSchema.Namespace;
                    }
                    if (writer.LookupPrefix(ns) == null)                      // it goes first (extraneous, but it makes att order compatible)
                    {
                        writer.WriteXmlnsAttribute(null, ns);
                    }
                    writer.WriteStartAttribute("type", XmlSchema.InstanceNamespace);
                    writer.WriteQualifiedName(name, ns);
                    writer.WriteEndAttribute();
                }
                QName predef = KnownTypeCollection.GetPredefinedTypeName(actualType);
                if (predef != QName.Empty)
                {
                    SerializePrimitive(type, graph, predef);
                }
                else
                {
                    map.Serialize(graph, this);
                }
            }
        }
Beispiel #2
0
        public void Serialize(Type type, object graph)
        {
            if (graph == null)
            {
                writer.WriteAttributeString("nil", XmlSchema.InstanceNamespace, "true");
            }
#if !MOONLIGHT
            else if (type == typeof(XmlElement))
            {
                ((XmlElement)graph).WriteTo(Writer);
            }
            else if (type == typeof(XmlNode []))
            {
                foreach (var xn in (XmlNode [])graph)
                {
                    xn.WriteTo(Writer);
                }
            }
#endif
            else
            {
                QName resolvedQName = null;
                if (resolver != null)
                {
                    XmlDictionaryString rname, rns;
                    if (resolver.TryResolveType(graph != null ? graph.GetType() : typeof(object), type, default_resolver, out rname, out rns))
                    {
                        resolvedQName = new QName(rname.Value, rns.Value);
                    }
                }

                Type actualType = graph.GetType();

                SerializationMap map;
                map = types.FindUserMap(actualType);
                // For some collection types, the actual type does not matter. So get nominal serialization type instead.
                // (The code below also covers the lines above, but I don't remove above lines to avoid extra search cost.)
                if (map == null)
                {
                    // FIXME: not sure if type.IsInterface is the correct condition to determine whether items are serialized with i:type or not. (e.g. bug #675144 server response).
                    actualType = types.GetSerializedType(type.IsInterface ? type : actualType);
                    map        = types.FindUserMap(actualType);
                }
                // If it is still unknown, then register it.
                if (map == null)
                {
                    types.Add(actualType);
                    map = types.FindUserMap(actualType);
                }

                if (actualType != type && (map == null || map.OutputXsiType))
                {
                    QName  qname = resolvedQName ?? types.GetXmlName(actualType);
                    string name  = qname.Name;
                    string ns    = qname.Namespace;
                    if (qname == QName.Empty)
                    {
                        name = XmlConvert.EncodeLocalName(actualType.Name);
                        ns   = KnownTypeCollection.DefaultClrNamespaceBase + actualType.Namespace;
                    }
                    else if (qname.Namespace == KnownTypeCollection.MSSimpleNamespace)
                    {
                        ns = XmlSchema.Namespace;
                    }
                    if (writer.LookupPrefix(ns) == null)                      // it goes first (extraneous, but it makes att order compatible)
                    {
                        writer.WriteXmlnsAttribute(null, ns);
                    }
                    writer.WriteStartAttribute("i", "type", XmlSchema.InstanceNamespace);
                    writer.WriteQualifiedName(name, ns);
                    writer.WriteEndAttribute();
                }
                QName predef = KnownTypeCollection.GetPredefinedTypeName(actualType);
                if (predef != QName.Empty)
                {
                    SerializePrimitive(type, graph, predef);
                }
                else
                {
                    map.Serialize(graph, this);
                }
            }
        }