1

I'm trying to deserialize the following xml document into a C# object:


<ns1:StockerFichiers
    xmlns:ns1="http://www.foo.fr/bar/Repository"
    xmlns:ns0="http://www.foo.fr/bar/Transport/">
    <ns1:fichiersAStocker>
        <ns0:FichierIdentifie>
            <ns0:Contenu></ns0:Contenu>
            <ns0:DomaineIdLocalDoc>128</ns0:DomaineIdLocalDoc>
            <ns0:EstOriginal>true</ns0:EstOriginal>
            <ns0:IdLocalDoc>2018-07-06T154554_70183_2</ns0:IdLocalDoc>
            <ns0:PieceDynamique>false</ns0:PieceDynamique>
            <ns0:GoldenSource>false</ns0:GoldenSource>
            <ns0:TypeDoc>PDF</ns0:TypeDoc>
            <ns0:TypeMime>application/pdf</ns0:TypeMime>
        </ns0:FichierIdentifie>
    </ns1:fichiersAStocker>
</ns1:StockerFichiers>

I know a lot of deserialization questions already exist, but even if some seems to be solving the same issue I face, None of what I've tried did populate my List<FichierIdentifie>.

Where I deserialize:


public void StockerFichiersXmlBase64(string fichiersAStocker)
        {

            //serializer 
            XmlRootAttribute xroot = new XmlRootAttribute();
            xroot.ElementName = "StockerFichiers";
            xroot.Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY; //ns1
            XmlSerializer deserializer = new XmlSerializer(typeof(StockerFichiersRoot),xroot );

            //fichiersAStocker is base64 encoded
            byte[] data = Convert.FromBase64String(fichiersAStocker);
            StringReader stringReader = new StringReader(Encoding.UTF8.GetString(data));

            //deserialization
            StockerFichiersRoot deserializedFiles = (StockerFichiersRoot)deserializer.Deserialize(stringReader);      
        }

My current version :

// Root
[XmlRoot(ElementName = "StockerFichiers", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
public class StockerFichiersRoot
{

    [XmlElement(ElementName = "fichiersAStocker", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
    public FichiersAStocker fichiersAStocker { get; set; }
}

//sub root
public class FichiersAStocker
{
    [XmlArray(ElementName = "fichiersAStocker", Namespace = NamespacesConstantes.NAMESPACE_SWREPOSITORY)]
    [XmlArrayItem(ElementName = "FichierIdentifie", Namespace=NamespacesConstantes.NAMESPACE_MSS_TRANSPORT)]
    public List<FichierIdentifie> FichiersIdentifie { get; set; }
}

public class FichierIdentifie
{

    [XmlElement(Namespace = NamespacesConstantes.NAMESPACE_TRANSPORT)]
    public byte[] Contenu { get; set; }

    //all fields are similar to the first one
}

And with this variation of the subroot class according to Is it possible to deserialize XML into List<T>? :


//sub root
public class FichiersAStocker
{
    [XmlElement(ElementName = "FichierIdentifie", Namespace=NamespacesConstantes.NAMESPACE_MSS_TRANSPORT)]
    public List<FichierIdentifie> FichiersIdentifie { get; set; }
}

I've also tried to remove the class FichiersAStocker (the sub root), to put the List<FichierIdentifie> in the root class, with both [xmlArray..] and [XmlElement] variations but with no success.

I always get an object with the list empty.

Amon
  • 296
  • 1
  • 14

2 Answers2

1

Try using XML2CSharp to generate class. Then try using that class or use it for debugging.

Generated code for your XML looks like this: (You can remove unwanted properties)

   /* 
Licensed under the Apache License, Version 2.0

http://www.apache.org/licenses/LICENSE-2.0
*/
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{
[XmlRoot(ElementName="FichierIdentifie",  Namespace="http://www.foo.fr/bar/Transport/")]
    public class FichierIdentifie {
    [XmlElement(ElementName="Contenu", Namespace="http://www.foo.fr/bar/Transport/")]
    public string Contenu { get; set; }
    [XmlElement(ElementName="DomaineIdLocalDoc", Namespace="http://www.foo.fr/bar/Transport/")]
    public string DomaineIdLocalDoc { get; set; }
    [XmlElement(ElementName="EstOriginal", Namespace="http://www.foo.fr/bar/Transport/")]
    public string EstOriginal { get; set; }
    [XmlElement(ElementName="IdLocalDoc", Namespace="http://www.foo.fr/bar/Transport/")]
    public string IdLocalDoc { get; set; }
    [XmlElement(ElementName="PieceDynamique", Namespace="http://www.foo.fr/bar/Transport/")]
    public string PieceDynamique { get; set; }
    [XmlElement(ElementName="SisraGoldenSource", Namespace="http://www.foo.fr/bar/Transport/")]
    public string SisraGoldenSource { get; set; }
    [XmlElement(ElementName="TypeDocSisra", Namespace="http://www.foo.fr/bar/Transport/")]
    public string TypeDocSisra { get; set; }
    [XmlElement(ElementName="TypeMime", Namespace="http://www.foo.fr/bar/Transport/")]
    public string TypeMime { get; set; }
}

[XmlRoot(ElementName="fichiersAStocker", Namespace="http://www.foo.fr/bar/Repository")]
public class FichiersAStocker {
    [XmlElement(ElementName="FichierIdentifie", Namespace="http://www.foo.fr/bar/Transport/")]
    public FichierIdentifie FichierIdentifie { get; set; }
}

[XmlRoot(ElementName="StockerFichiers", Namespace="http://www.foo.fr/bar/Repository")]
public class StockerFichiers {
    [XmlElement(ElementName="fichiersAStocker", Namespace="http://www.foo.fr/bar/Repository")]
    public FichiersAStocker FichiersAStocker { get; set; }
    [XmlAttribute(AttributeName="ns1", Namespace="http://www.w3.org/2000/xmlns/")]
    public string Ns1 { get; set; }
    [XmlAttribute(AttributeName="ns0", Namespace="http://www.w3.org/2000/xmlns/")]
    public string Ns0 { get; set; }
}

}
Matt
  • 1,245
  • 2
  • 17
  • 32
  • Thanks for your quick answer ! The things is that we can have multiple `FichierIdentifie`. According to XML2CSharp, the class FichiersAStocker doesn't change really much,(it gives me the same as my "variation" in my main post) however, it doesn't change anything, my List isn't populated. Any Idea Why ? – Amon Jun 28 '19 at 10:17
  • Is this the complete XML you are using? Can you include a code which you are using for populating values? – Matt Jun 28 '19 at 10:29
  • Yes it is the entire xml I'm using for my tests, and I don't have acces to the webservice giving me the xml :/ But whatever way the xml is produced, it shouln't change the things that I should be able to deserialize it, no ? – Amon Jun 28 '19 at 10:38
  • I can't give you the complete working things because it's part of a huge WCF Solution but 'ill try to give you what you will need! :D – Amon Jun 28 '19 at 11:31
  • Just try to extract the part of the deserialization code with XML as string variable. – Matt Jun 28 '19 at 11:32
  • I found the solution ! – Amon Jun 28 '19 at 11:41
  • Well, glad to be your rubber duck ;) – Matt Jun 28 '19 at 11:42
1

Really frustrating mistake that took me half a day to solve :

notice how "NamespacesConstantes.NAMESPACE_MSS_TRANSPORT" is close to "NamespacesConstantes.NAMESPACE_TRANSPORT". Add some lazy autocompletion and you can fool yourself while defining the [XmlElement...] in the "FichiersAStocker" class.

Thanks for your help Matt, I noticed this mistake while i paste some of my code on https://dotnetfiddle.net/ ! :)

Amon
  • 296
  • 1
  • 14