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 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); } }
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()); }
protected virtual IList CreateOutputFrom(ListPropertyDescriptor metadata, IList items, Type itemType) { Array arrayItems = Array.CreateInstance(itemType, items.Count); for (int i = 0; i < items.Count; i++) { arrayItems.SetValue(items[i], i); } return(arrayItems); }
private void WriteInlineArrayAsElement(object parent, ListPropertyDescriptor metadata, object entity, Type entityType, XmlTextWriter writer, XmlSerializerContext context) { IEnumerable list = (IEnumerable)entity; if (!context.Settings.WriteEmptyLists) { if (!list.GetEnumerator().MoveNext()) { return; } } string nodeName = metadata.GetElementNameForType(entityType, context, true); //escribo el inicio del nodo writer.WriteStartElement(nodeName); if (!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()); } list = (IEnumerable)entity; string value = this.GetInlineStringArray(metadata, list, entityType, context, false); //escribo el contenido del array writer.WriteString(value); } else { //me fijo si ya existe en el context long id = context.Stack.GetInstanceReferenceId(entity); writer.WriteAttributeString(XmlSerializerSettings.ObjectReferenceAttributeName, id.ToString()); } writer.WriteEndElement(); }
private void WriteInlineArrayAsAttribute(object parent, ListPropertyDescriptor metadata, object entity, Type entityType, XmlTextWriter writer, XmlSerializerContext context) { IEnumerable list = (IEnumerable)entity; if (!context.Settings.WriteEmptyLists) { if (!list.GetEnumerator().MoveNext()) { return; } } string value = this.GetInlineStringArray(metadata, list, entityType, context, true); string attributeName = metadata.GetAttributeNameForType(entityType, context); //esta definido el atributo, lo escribo writer.WriteAttributeString(attributeName, value); }
protected override void DoToXml(object parent, PropertyDescriptor propDesc, object entity, XmlTextWriter writer, XmlSerializerContext context) { Type entityType = entity.GetType(); ListPropertyDescriptor metadata = propDesc.GetPropertyDescriptor <ListPropertyDescriptor>(entityType, context); if (metadata.IsInlineAttributeArray(entityType, context)) { this.WriteInlineArrayAsAttribute(parent, metadata, entity, entityType, writer, context); } else { //deberia validar si la lista ya se agrego....y colocar una referencia.. if (metadata.IsInlineElementArray(entityType, context)) { this.WriteInlineArrayAsElement(parent, metadata, entity, entityType, writer, context); } else { this.WriteArrayAsElement(parent, metadata, entity, entityType, writer, context); } } }
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); }
protected override object DoFromXml(object parent, PropertyDescriptor propDesc, Type entityType, XmlReader reader, XmlSerializerContext context) { //string nodeName = reader.LocalName; ListPropertyDescriptor metadata = propDesc.GetPropertyDescriptor <ListPropertyDescriptor>(entityType, context); IList items; //creo una lista para luego transformarla en un array....si es una lista if (entityType.IsArray) { items = new ArrayList(); } else if (entityType.IsInterface) { if (entityType.IsGenericType) { Type entityItemType = entityType.GetGenericArguments()[0]; Type listType = typeof(List <>); listType = listType.MakeGenericType(entityItemType); items = (IList)Activator.CreateInstance(listType, true); } else { items = new ArrayList(); } } else { items = (IList)Activator.CreateInstance(entityType, true); } Type itemType; long id = 0; if (metadata.IsInlineAttributeArray(entityType, context)) { itemType = this.DeserializeItemsFromInlineAttribute(entityType, items, metadata, reader, context); } else { //si no es inline el array, entonces tiene un id id = this.GetInstanceId(reader); //recorro todos los items if (reader.NodeType == XmlNodeType.EndElement || reader.IsEmptyElement) { //avanzo if (reader.IsEmptyElement) { reader.Read(); //avanzo para ubicarme en el siguiente nodo. } itemType = metadata.DeclaringItemType; } else { if (metadata.IsInlineElementArray(entityType, context)) { itemType = this.DeserializeItemsFromInlineElements(items, metadata, reader, context); } else { itemType = this.DeserializeItemsFromElements(entityType, items, metadata, reader, context); } } } IList output; //creo un array if (entityType.IsArray) { output = this.CreateOutputFrom(metadata, items, entityType.GetElementType()); } else { output = this.CreateOutputFrom(metadata, items, itemType); } //agrego la instancia al stack context.Stack.AddInstance(id, output); return(output); }
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 static PropertyDescriptorCollection GetExtendedProperties( PropertyDescriptorCollection pdc, Type itemType, string propertyPrefix, Type[] parentTypes, PropertyDescriptor[] parentAccessors, IsNullHandler isNull) { ArrayList list = new ArrayList(pdc.Count); ArrayList objects = new ArrayList(); bool isDataRow = itemType.IsSubclassOf(typeof(DataRow)); foreach (PropertyDescriptor p in pdc) { Type propertyType = p.PropertyType; if (p.Attributes.Matches(BindableAttribute.No) || //propertyType == typeof(Type) || isDataRow && p.Name == "ItemArray") { continue; } bool isList = false; bool explicitlyBound = p.Attributes.Contains(BindableAttribute.Yes); PropertyDescriptor pd = p; if (propertyType.GetInterface("IList") != null) { //if (!explicitlyBound) // continue; isList = true; pd = new ListPropertyDescriptor(pd); } if (!isList && !propertyType.IsValueType && !propertyType.IsArray && (!propertyType.FullName.StartsWith("System.") || explicitlyBound || propertyType.IsGenericType) && propertyType != typeof(Type) && propertyType != typeof(string) && propertyType != typeof(object) && Array.IndexOf(parentTypes, propertyType) == -1) { Type[] childParentTypes = new Type[parentTypes.Length + 1]; parentTypes.CopyTo(childParentTypes, 0); childParentTypes[parentTypes.Length] = itemType; PropertyDescriptor[] childParentAccessors = new PropertyDescriptor[parentAccessors.Length + 1]; parentAccessors.CopyTo(childParentAccessors, 0); childParentAccessors[parentAccessors.Length] = pd; PropertyDescriptorCollection pdch = GetAccessor(propertyType).PropertyDescriptors; pdch = pdch.Sort(new PropertyDescriptorComparer()); pdch = GetExtendedProperties( pdch, propertyType, propertyPrefix + pd.Name + "+", childParentTypes, childParentAccessors, isNull); objects.AddRange(pdch); } else { if (propertyPrefix.Length != 0 || isNull != null) { pd = new StandardPropertyDescriptor(pd, propertyPrefix, parentAccessors, isNull); } list.Add(pd); } } list.AddRange(objects); return(new PropertyDescriptorCollection( (PropertyDescriptor[])list.ToArray(typeof(PropertyDescriptor)))); }
protected override IList CreateOutputFrom(ListPropertyDescriptor metadata, IList items, Type itemType) { return(items); }