0

So i need to xml serialize a generic list of objects where the object consists of another list and a string.

This is what i get now

    <?xml version="1.0" encoding="UTF-8"?>

-<ArrayOfRecept xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">


-<Recept>
<Namn>Nomnom</Namn>    
</Recept>

-<Recept>    
<Namn>Ännu mer nomnom</Namn>    
</Recept>

</ArrayOfRecept>

Here only the string value is serialized and not my List

This is my object that i want to serialize

public class Recept
    {

        private ListHanterare<string> ingredienser;
        private string namn;

        public Recept()
        {
            ingredienser = new ListHanterare<string>();
        }
        public ListHanterare<string> Ingredienser
        {
            get { return ingredienser; }

        }

        public string Namn
        {
            get { return namn; }
            set { namn = value; }
        }

    }

So I will have a list of Recept that i want to xml serialize and I want the xml to show both "Namn" and the "Ingredienser"-list.

This is my serializer

 class XMLSerial
    {
        public static bool Serialize<T>(T obj, string filePath)
        {
            bool bok = true;

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            TextWriter writer = new StreamWriter(filePath);
            try
            {
                serializer.Serialize(writer, obj);
            }
            catch
            {
                bok = false;
            }
            finally
            {
                if (writer != null)

                    writer.Close();
            }

            return bok;
        }

    }

This is inside the ListHanterare class where I pass the object to the serializer

public bool XMLSerialize(string filePath){
            return XMLSerial.Serialize<List<T>>(lista, filePath);

EDIT: So by adding a setter to ingredienser I now get this

-<Recept>
<Ingredienser/>
<Namn>rec</Namn>
</Recept>

But ingredienser is still empty My ListHanterare class is a basic generic List class

public class ListHanterare<T> : IListHanterare<T>
    {

        private List<T> lista; // This is the list
        private int count;

        public ListHanterare()
        {
            lista = new List<T>();

        }

So i need to serialize a ListHanterare list of Recept objects where the Recept object consists of a string and another ListHanterare list of strings, the string is serialized correctly but not the list of strings.

user3621898
  • 589
  • 5
  • 24
  • Add XML Element to your Recept Class so your Serializer would know what to Deserialize. Also, you're not Deserializing your Elements you're just streaming and returning the value as TRUE - bool. You're not returning anything its either false or true. – Aizen Apr 05 '15 at 00:28
  • I have a [Serializable] above my class declaration – user3621898 Apr 05 '15 at 12:30
  • `[Serializable]` is for binary formatting not `XmlSerializer`. – dbc Apr 05 '15 at 18:56

1 Answers1

0

In order for XmlSerializer to serialize or deserialize the property Ingredienser of your Recept class, it must have a public setter as well as a public getter:

    public ListHanterare<string> Ingredienser
    {
        get { return ingredienser; }
        set { ingredienser = value; } 
    }

If you don't do this, XmlSerializer will ignore the property.

You might still have problems with the class ListHanterare, but it's not shown in your question.

DataContractSerializer does not have this requirement. However, to serialize and deserialize your classes with DataContractSerializer and include private fields or properties, you would need to fully annotate them with data contract attributes. Private field and properties marked with [DataMember] get serialized despite being private. Data contract serialization is opt-in, however, so to use this feature your classes would need to be fully attributed.

Update

You don't show the complete code of your ListHanterare<string> class. In order for XmlSerializer to serialize and deserialize it successfully, it must either:

  1. Make all its contents available in publicly settable and gettable properties, or
  2. Implement ICollection<T> (or even IList<T>) as described here: XmlSerializer Class.

For method #1, you could modify your class as follows:

public class ListHanterare<T> 
{
    private List<T> lista; // This is the list
    private int count;

    public ListHanterare()
    {
        lista = new List<T>();
    }

    [XmlElement("Item")]
    public T[] SerializableList
    {
        get
        {
            return (lista == null ? new T [0] : lista.ToArray());
        }
        set
        {
            if (lista == null)
                lista = new List<T>();
            lista.Clear();
            lista.AddRange(value ?? Enumerable.Empty<T>());
            count = lista.Count;
        }
    }
}

You will now see the items serialized your XML.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • By giving it a setter gave me this result hehe Would using DataContractSerializer fix this ? – user3621898 Apr 05 '15 at 11:49
  • @user3621898 - what does your `ListHanterare` class look like? If its contents are not being serialized, the problem may be there. – dbc Apr 05 '15 at 14:43
  • @user3621898 - Probably your `ListHanterare` does not have the publicly settable properties required by `XmlSerializer` -- but I can't say for sure. Can you show the complete code of `ListHanterare`? – dbc Apr 05 '15 at 18:56
  • Your code worked thank you, could you explain how the get line works there? also the double questionmark line – user3621898 Apr 05 '15 at 23:25
  • The result i get looks sthg like this ingrediens is there anyway to make it without the serializable tag ? – user3621898 Apr 05 '15 at 23:32
  • @user3621898 - the `[XmlElement("Item")]` should have eliminated the `SerializableList` element from the XML. Did you remove it? The `??` line is to avoid throwing an exception on a `null` input. – dbc Apr 06 '15 at 03:06