private void WriteArrayAsElement(object parent, ListPropertyDescriptor metadata, object entity, Type entityType, XmlTextWriter writer, XmlSerializerContext context) { if (!context.Settings.WriteEmptyLists) { IEnumerable list = (IEnumerable)entity; if (!list.GetEnumerator().MoveNext()) { return; } } string nodeName = metadata.GetElementNameForType(entityType, context, true); //escribo el inicio del nodo writer.WriteStartElement(nodeName); if (!context.Settings.UniqueSerializationForInstance || !context.Stack.ContainsInstance(entity)) { //agrego la lista a las entidades registradas long id = context.Stack.AddInstance(entity); //escribo el tipo, si corresponde base.WriteTypeDefinition(metadata, entityType, context, writer); //escribo el id del objeto si corresponde if (context.Settings.UniqueSerializationForInstance) { writer.WriteAttributeString(XmlSerializerSettings.ObjectIdAttributeName, id.ToString()); } IEnumerable list = (IEnumerable)entity; Type itemType; IXmlConverter itemConverter; //recorro todos los items foreach (object item in list) { if (item != null) { itemType = item.GetType(); itemConverter = context.GetConverter(itemType); ListItemPropertyDescriptor descriptor = metadata.GetItemPropertyDescriptor(context, false); itemConverter.ToXml(entity, descriptor, item, writer, context); } else { itemConverter = context.GetConverter(null); itemConverter.ToXml(entity, metadata, null, writer, context); } } } else { //me fijo si ya existe en el context long id = context.Stack.GetInstanceReferenceId(entity); writer.WriteAttributeString(XmlSerializerSettings.ObjectReferenceAttributeName, id.ToString()); } writer.WriteEndElement(); }
private Type DeserializeItemsFromElements(Type entityType, IList parent, ListPropertyDescriptor metadata, XmlReader reader, XmlSerializerContext context) { ListItemPropertyDescriptor propDesc = metadata.GetItemPropertyDescriptor(context, false); //avanzo hasta la posicion del elemento string nodeName = reader.LocalName; //avanzo hasta el primer nodo bool end = !reader.Read(); XmlNodeType typeNode = reader.MoveToContent(); object association; Type itemType = null; //parseo las propiedades while (!end) { //me fijo si la propiedad es vacia if (reader.NodeType != XmlNodeType.EndElement) { //obtengo el tipo por el atributo itemType = base.GetEntityTypeForElement(propDesc, reader, context); if (itemType != null) { IXmlConverter converter = context.GetConverter(itemType); association = converter.FromXml(parent, propDesc, itemType, reader, context); if (association != null || context.Settings.AddNullValueInLists) { //agrego el item a la lista parent.Add(association); } } else { reader.Skip(); } } //avanzo... typeNode = reader.MoveToContent(); end = reader.NodeType == XmlNodeType.EndElement && reader.LocalName.Equals(nodeName); } reader.Read(); if (entityType.IsArray && itemType != null) { return(itemType); } else { return(metadata.DeclaringItemType); } }
private string GetInlineStringArray(ListPropertyDescriptor metadata, IEnumerable list, Type entityType, XmlSerializerContext context, bool isAttribute) { Type itemType = null; Type currentType = null; ValueTypeConverter itemConverter = null; StringBuilder attBuilder = new StringBuilder(); ValueTypePropertyDescriptor valPropDesc = null; string itemSeparator = metadata.GetInlineItemSeparator(entityType, context, isAttribute); bool first = true; foreach (object item in list) { if (item != null) { if (itemType == null) { itemType = item.GetType(); if (!TypeHelper.IsValueType(itemType)) { throw new Exception("El item de tipo " + itemType.Name + " no es de tipo ValueType, no puede serializarse en un atributo."); } itemConverter = (ValueTypeConverter)context.GetConverter(itemType); ListItemPropertyDescriptor itemDesc = metadata.GetItemPropertyDescriptor(context, true); valPropDesc = itemDesc.GetPropertyDescriptor <ValueTypePropertyDescriptor>(itemType, context); } currentType = item.GetType(); if (!currentType.Equals(itemType)) { throw new Exception("El item de tipo " + currentType.Name + " es direferente al primer item del array de tipo " + itemType.Name + ". No es posible serializar un array de diferentes tipos en un atributo."); } string val = itemConverter.GetValueAsString(valPropDesc, item, itemType, context); if (first) { first = false; } else { attBuilder.Append(itemSeparator); } attBuilder.Append(val); } } return(attBuilder.ToString()); }
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { if (value is IList) { IList list = (IList) value; PropertyDescriptor[] properties = new PropertyDescriptor[list.Count]; for (int n = 0; n < list.Count; n++) properties[n] = new ListItemPropertyDescriptor(n, list[n]); return new PropertyDescriptorCollection(properties, true); } return base.GetProperties(context, value, attributes); }
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { if (value is IList) { IList list = (IList)value; PropertyDescriptor[] properties = new PropertyDescriptor[list.Count]; for (int n = 0; n < list.Count; n++) { properties[n] = new ListItemPropertyDescriptor(n, list[n]); } return(new PropertyDescriptorCollection(properties, true)); } return(base.GetProperties(context, value, attributes)); }
private Type DeserializeItemsFromInlineAttribute(Type entityType, IList parent, ListPropertyDescriptor metadata, XmlReader reader, XmlSerializerContext context) { //avanzo hasta la posicion del elemento string attributeName = reader.Name; string value = reader.Value; //obtengo el tipo por el atributo ListItemPropertyDescriptor propDesc = metadata.GetItemPropertyDescriptor(context, true); Type itemType = propDesc.GetTypeFromAttributeName(attributeName, context); if (!string.IsNullOrEmpty(value)) { this.DeserializeItems(entityType, itemType, parent, metadata, propDesc, value, context, true); } return(itemType); }
private Type DeserializeItemsFromInlineElements(IList parent, ListPropertyDescriptor metadata, XmlReader reader, XmlSerializerContext context) { //avanzo hasta la posicion del elemento string nodeName = reader.LocalName; Type itemType = metadata.DeclaringItemType; if (reader.NodeType != XmlNodeType.EndElement) { //obtengo el tipo por el atributo ListItemPropertyDescriptor propDesc = metadata.GetItemPropertyDescriptor(context, true); itemType = base.GetEntityTypeForElement(propDesc, reader, context); if (itemType != null) { //avanzo hasta el primer nodo if (reader.Read() && reader.NodeType != XmlNodeType.EndElement) { XmlNodeType typeNode = reader.MoveToContent(); string val = reader.Value; this.DeserializeItems(parent.GetType(), itemType, parent, metadata, propDesc, val, context, false); reader.Read(); } } else { reader.Skip(); } } reader.Read(); return(itemType); }
private void DeserializeItems(Type entityType, Type itemType, IList parent, ListPropertyDescriptor metadata, ListItemPropertyDescriptor propDesc, string itemsStr, XmlSerializerContext context, bool isAttribute) { itemsStr = itemsStr.Trim(); if (!TypeHelper.IsValueType(itemType)) { throw new Exception("El item de tipo " + itemType.Name + " no es de tipo ValueType, no puede deserializarse de un atributo."); } ValueTypeConverter itemConverter = (ValueTypeConverter)context.GetConverter(itemType); //obtengo el tipo por el atributo ValueTypePropertyDescriptor itemDescriptor = propDesc.GetPropertyDescriptor <ValueTypePropertyDescriptor>(itemType, context); string itemSeparator = metadata.GetInlineItemSeparator(entityType, context, isAttribute); string[] items = itemsStr.Split(new string[] { itemSeparator }, StringSplitOptions.None); int last = items.Length; if (string.Compare(itemsStr[itemsStr.Length - 1].ToString(), itemSeparator) == 0) { last--; } object val; for (int i = 0; i < last; i++) { string item = items[i]; val = itemConverter.GetValueFromString(itemDescriptor, item, itemType, context); parent.Add(val); } }