public XElement SerializeRoot(object obj, Type rootType, XName name, XSerializerNamespaceCollection namespaces, SerializationScope globalScope) { Debug.Assert(rootType.IsInstanceOfType(obj)); Debug.Assert(namespaces != null); var root = SerializeXElement(obj, rootType, name, globalScope); //导入命名空间。 foreach (var ns in namespaces) root.SetAttributeValue(XNamespace.Xmlns + ns.Prefix, ns.Uri); //处理导入的类型。 var nsCounter = 0; foreach (var descendant in root.Descendants()) { var actualTypeName = descendant.Annotation<XName>(); if (actualTypeName != null) { if (actualTypeName.Namespace == descendant.GetDefaultNamespace()) { descendant.SetAttributeValue(SerializationHelper.Xsi + "type", actualTypeName.LocalName); } else { var prefix = descendant.GetPrefixOfNamespace(actualTypeName.Namespace); if (prefix == null) { nsCounter++; prefix = "nss" + nsCounter; descendant.SetAttributeValue(XNamespace.Xmlns + prefix, actualTypeName.NamespaceName); } descendant.SetAttributeValue(SerializationHelper.Xsi + "type", prefix + ":" + actualTypeName.LocalName); } descendant.RemoveAnnotations<XName>(); } } return root; }
public object DeserializeRoot(XElement e, object existingObject, Type rootType, SerializationScope globalScope) { var obj = DeserializeXElement(e, existingObject, rootType, globalScope); if (!rootType.IsInstanceOfType(obj)) throw new InvalidOperationException("Invalid root element : " + e.Name); return obj; }
public object DeserializeXCollectionItem(XElement e, SerializationScope typeScope) { //Debug.Print("DC : {0}\t{1}", e, typeScope); Debug.Assert(typeScope != null); var t = typeScope.GetType(e.Name); if (t == null) throw new NotSupportedException(string.Format(Prompts.UnregisteredType, e.Name, typeScope)); return DeserializeXElement(e, null, t, typeScope); }
// param : obj is the current value of property / field. public object DeserializeXProperty(XElement e, object obj, Type defaultType, SerializationScope childItemsTypeScope) { //Debug.Print("DP : {0}\t{1}", e, childItemsTypeScope); return DeserializeXElement(e, obj, defaultType, childItemsTypeScope); }
// typeScope is applied for child items, rather than obj itself. private XElement SerializeXElement(object obj, Type defaultType, XName name, SerializationScope typeScope) { Debug.Assert(obj != null && defaultType != null && name != null); var objType = obj.GetType(); var objTypeName = _Builder.GlobalScope.GetName(objType); if (objTypeName == null) throw new NotSupportedException(string.Format(Prompts.UnregisteredType, objType, _Builder.GlobalScope)); var s = _Builder.GetSerializer(objType); var e = new XElement(name); //如果名义类型和实际类型不同,则注明实际类型。 //如果是 TypeScope 中未定义的类型,则使用对应的元素名,而不使用 xsi:type if (name != objTypeName && objType != defaultType) { //先将 XName 加入批注,到根节点中处理。 e.AddAnnotation(objTypeName); } //一般不会调用到此处,除非 obj 是根部节点,或是集合中的一项。 if (s == null) throw new NotSupportedException(string.Format(Prompts.UnregisteredType, objType, typeScope)); EnterObjectSerialization(obj); s.Serialize(e, obj, this, typeScope); ExitObjectSerialization(obj); return e; }
private object DeserializeXElement(XElement e, object obj, Type defaultType, SerializationScope typeScope) { Debug.Assert(e != null && defaultType != null); // 对于集合,从元素名推理对象类型。 var xsiTypeName = (string)e.Attribute(XsiType); Type objType; if (xsiTypeName == null) { //未指定 xsi:type,则使用 defaultType objType = defaultType; } else { //指定了 xsi:type //解析 prefix:localName var parts = xsiTypeName.Split(':'); XName xName; if (parts.Length <= 1) xName = e.GetDefaultNamespace() + xsiTypeName; else xName = e.GetNamespaceOfPrefix(parts[0]) + parts[1]; objType = _Builder.GlobalScope.GetType(xName); if (objType == null) throw new NotSupportedException(string.Format(Prompts.UnregisteredType, xsiTypeName, typeScope)); } var s = _Builder.GetSerializer(objType); if (s == null) throw new NotSupportedException(string.Format(Prompts.UnregisteredType, objType, typeScope)); return s.Deserialize(e, obj, this, typeScope); }
// Serialize Collection or Complex objects public XElement SerializeXProperty(object obj, Type defaultType, XName name, SerializationScope childItemsTypeScope) { //Debug.Print("SP : {0}\t{1}\t{2}", name, obj, childItemsTypeScope); if (obj != null) return SerializeXElement(obj, defaultType, name, childItemsTypeScope); return null; }
public XElement SerializeXCollectionItem(object obj, Type defaultType, SerializationScope typeScope) { //Debug.Print("SC : {0}\t{1}", obj, typeScope); Debug.Assert(typeScope != null); var nominalType = obj.GetType(); var objTypeName = typeScope.GetName(nominalType); if (objTypeName == null) { objTypeName = typeScope.GetName(defaultType); nominalType = defaultType; } return SerializeXElement(obj, nominalType, objTypeName, null); }
private static bool WriteIfPrimitiveOrNull(BinaryWriter writer, DObject.TypeCode type, object value, out SerializationScope scope) { if (type != DObject.TypeCode.DObject && !type.HasFlag(DObject.TypeCode.Array)) { scope = null; switch (type) { case DObject.TypeCode.Boolean: writer.Write((bool)value); return(true); case DObject.TypeCode.Char: writer.Write((char)value); return(true); case DObject.TypeCode.SByte: writer.Write((sbyte)value); return(true); case DObject.TypeCode.Byte: writer.Write((byte)value); return(true); case DObject.TypeCode.Int16: writer.Write((short)value); return(true); case DObject.TypeCode.UInt16: writer.Write((ushort)value); return(true); case DObject.TypeCode.Int32: writer.Write((int)value); return(true); case DObject.TypeCode.UInt32: writer.Write((uint)value); return(true); case DObject.TypeCode.Int64: writer.Write((long)value); return(true); case DObject.TypeCode.UInt64: writer.Write((ulong)value); return(true); case DObject.TypeCode.Single: writer.Write((float)value); return(true); case DObject.TypeCode.Double: writer.Write((double)value); return(true); case DObject.TypeCode.Decimal: writer.Write((decimal)value); return(true); case DObject.TypeCode.DateTime: writer.Write(((DateTime)value).ToBinary()); return(true); case DObject.TypeCode.TimeSpan: writer.Write(((TimeSpan)value).Ticks); return(true); case DObject.TypeCode.String: if (value == null) { writer.Write((byte)0); } else { writer.Write((byte)1); writer.Write((string)value); } return(true); case DObject.TypeCode.Guid: writer.Write(((Guid)value).ToByteArray()); return(true); default: throw new ArgumentOutOfRangeException("type", type, null); } } if (value == null) { writer.Write(-1); scope = null; return(true); } if (type == DObject.TypeCode.DObject) { DObject dObject = (DObject)value; if (dObject.Count < 1) { writer.Write(0); scope = null; return(true); } writer.Write(dObject.Count); scope = new SerializationScope(dObject); return(false); } Array array = (Array)value; if (array.Length < 1) { writer.Write(0); scope = null; return(true); } writer.Write(array.Length); scope = new SerializationScope(array, type); return(false); }
//-------------------------------------------------------------------------------------------------- public SerializationContext(SerializationScope scope = SerializationScope.Storage) { Scope = scope; Result = SerializationResult.None; }