0

I try to load a list from an xml file. I have different lists of my custom classes and different xml files. The plan was to create one method to be able to deserialize all of them like this:

ListDependencies.Deserialize(DependenciesPath);
ListProfessions.Deserialize(ProfessionsPath);
ListCategories.Deserialize(CategoriesPath);
...

When deserializing I get the error that the xml file had an unexpected format.

    public static List<T> Deserialize<T>(this T value, string _path)
    {
        var xmlserializer = new XmlSerializer(typeof(List<T>));

        using (StreamReader sr = new StreamReader(_path, Encoding.Unicode))
        {
            using (var reader = XmlReader.Create(sr.BaseStream))
            {
                return (List<T>)xmlserializer.Deserialize(reader);
            }
        }
    }

Inner Exception:

{"<ArrayOfDependencyObject xmlns=''> was not expected."} System.Exception {System.InvalidOperationException}

XmlContent:

<ArrayOfDependencyObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <DependencyObject>
    <Profession>80dd893e-9eb6-42c6-9b60-a61b87df0d1b</Profession>
    <Dependency>f76c72be-f2da-435b-b1f8-a4775c0bc1f1</Dependency>
  </DependencyObject>
  <DependencyObject>
    <Profession>8ab9b108-dd4b-4639-b323-c7a6c28f1314</Profession>
    <Dependency>9b86ff1d-c1de-4f95-adc8-413a94714cc0</Dependency>
  </DependencyObject>
  <DependencyObject>
    <Profession>5a273efa-eb29-4ea0-bd1d-2bb84727aa1e</Profession>
    <Dependency>954bd3d6-e78e-424e-bd69-8b46f239c5f2</Dependency>
  </DependencyObject>
</ArrayOfDependencyObject>

Can anyone help me?

Jawad
  • 11,028
  • 3
  • 24
  • 37
  • Have you tried to add the namespace to serializer? Like here for [example](https://stackoverflow.com/questions/2339782/xml-serialization-and-namespace-prefixes) – leopcode Jan 08 '20 at 15:11
  • Did you notice you don't use "value" in your extension method, except maybe for type-inference ? You pass a ListDependencies Variable, but you don't do anything with it. – Holger Jan 08 '20 at 15:31
  • Does this answer your question? [Deserializing xml, including namespace](https://stackoverflow.com/questions/31935409/deserializing-xml-including-namespace) – Jawad Jan 08 '20 at 15:51
  • @leo_acm94 I'm not sure what headers to add. As I understood that article was about deserializing an xml with that had headers the person couldn't remove. – Nico Mayer Jan 08 '20 at 16:36
  • @Holger Thats the part that I don't entirely understand too. If I add the 'this T value' I can call that method from my list directly (ListDependencies.Deserialize(_path). If I remove it, I cannot do that anymore. I somehow thought it should be possible to get the type of list I am calling the method from and convert the return value accordingly: ListDependencies.Deserialize() -> return List ListCategories.Deserialize() -> return List etc – Nico Mayer Jan 08 '20 at 16:39

1 Answers1

0

What I see from the XML is an object with array of elements. Change the Deserialize method as below and try again

public static T Deserialize<T>(this T value, string _path)
{
    var xmlserializer = new XmlSerializer(typeof(T));

    using (StreamReader sr = new StreamReader(_path, Encoding.Unicode))
    {
        using (var reader = XmlReader.Create(sr.BaseStream))
        {
            return (T)xmlserializer.Deserialize(reader);
        }
    }
}

I have tried this method with the given XML

var ListDependencies = new ArrayOfDependencyObject();
var results = ListDependencies.Deserialize(xmlFile);
foreach (var element in results.DependencyObject)
{
    Console.WriteLine($"{element.Profession}:{element.Dependency}");
}

and got this Output

80dd893e-9eb6-42c6-9b60-a61b87df0d1b:f76c72be-f2da-435b-b1f8-a4775c0bc1f1
8ab9b108-dd4b-4639-b323-c7a6c28f1314:9b86ff1d-c1de-4f95-adc8-413a94714cc0
5a273efa-eb29-4ea0-bd1d-2bb84727aa1e:954bd3d6-e78e-424e-bd69-8b46f239c5f2
Krishna Varma
  • 4,238
  • 2
  • 10
  • 25
  • This is working much better. I have adjusted the Deserialize mehtod as you suggested and are able to get the list with this code: `var result = ListDependencies.Deserialize(DependenciesPath);` `ListDependencies = (List)result;` So right now the best result. Is there a way to do get the type of List and do the cast in the `Deserialize` method? – Nico Mayer Jan 08 '20 at 16:54
  • 1
    Actually this is the solution. It works with `ListProfessions = ListProfessions.Deserialize(Path)' too. No cast needed. So Thank you. – Nico Mayer Jan 08 '20 at 17:13