Avatar billede jesperwerge Nybegynder
21. november 2007 - 17:53 Der er 8 kommentarer og
1 løsning

XmlSerialize objects med Array eller List typer

Hej eksperter

Jeg har en klasse som skal XmlSerilizeres. Klassen består af 2 typer af "felter": 1 felt af objekt typen KUNDE og et Array af objekt typen REPORTER (har også prøvet typen List).

denne klasse der vil betå af 1 KUNDE og X antal af REPORTER vil jeg gerne Serialisere.

At tilføje KUNDE og REPORTER til klassen er ikke noget problem, men når jeg forsøger at bruge XmlSerialize.Serialize får jeg en fejl:

Message: There was an error reflecting type <klassensNavn>
InnerText: There was an error reflecting field 'reportsArray'.

reportArray er min Array af REPORTER

Min kode for klassen ser således ud:

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

namespace MinConsole
{
  [System.SerializableAttribute()]
  public class sObject
  {
    public cWebService.KUNDE customer;
    public rWebService.REPORTER [] reportsArray;
  }
}

Jeg har søgt på nettet omkring Serialize array eller List typer, men synes ikke helt jeg forstår hvordna det kan gøres, hvis det kan.

håber en af jer har prøvet dette eller måske kan forsøge med en løsning.
Avatar billede jesperwerge Nybegynder
21. november 2007 - 18:26 #1
Fejlen kommer når jeg forsøger at oprette en XmlSerializer, koden:

Type [] extraTypes= new Type[3];
extraTypes[0] = typeof(cWebService.KUNDER);
extraTypes[1] = typeof(rWebService.REPORTER);
extraTypes[2] = typeof(Array);

XmlSerializer oSerializer = new XmlSerializer(typeof(sObject), extraTypes);

Frustrerende - håber der er en venlig sjæl der kan hjælpe.

/werge
Avatar billede nielle Nybegynder
21. november 2007 - 18:30 #2
Sådan?

    class Program
    {
        static void Main(string[] args)
        {
            string fileName = @"C:\e806932.xml";

            // Serializering
            sObject so1 = new sObject("jesperwerge");

            FileStream fs1 = new FileStream(fileName, FileMode.Create);
            XmlSerializer xs1 = new XmlSerializer(typeof(sObject));
            xs1.Serialize(fs1, so1);
            fs1.Close();

            // Deserializering

            FileStream fs2 = new FileStream(fileName, FileMode.Open);
            XmlSerializer xs2 = new XmlSerializer(typeof(sObject));

            sObject so2 = xs2.Deserialize(fs2) as sObject;

            fs1.Close();

            // Verifikation

            Console.WriteLine(so2.customer.navn);
        }
    }

    [Serializable]
    public class sObject
    {
        public Kunde customer;
        public Rapport[] reportsArray;

        // For at kunne serializeres skal der være en constructor uden parametre.
        public sObject() { }

        public sObject(string navn)
        {
            this.customer = new Kunde(navn);

            // Bare et eksempel med 10 rapport-opbjekter.
            List<Rapport> rapportList = new List<Rapport>();
            for (DateTime rapportDato = DateTime.Now;
                rapportDato > DateTime.Now.AddDays(-10);
                rapportDato = rapportDato.AddDays(-1))
            {
                rapportList.Add(new Rapport(rapportDato));
            }
            this.reportsArray = rapportList.ToArray();
        }
    }

    [Serializable]
    public class Kunde
    {
        public string navn;

        // For at kunne serializeres skal der være en constructor uden parametre.
        public Kunde() { }

        public Kunde(string navn)
        {
            this.navn = navn;
        }
    }

    [Serializable]
    public class Rapport
    {
        public DateTime rapportDato;

        // For at kunne serializeres skal der være en constructor uden parametre.
        public Rapport() { }

        public Rapport(DateTime rapportDato)
        {
            this.rapportDato = rapportDato;
        }
    }
Avatar billede jesperwerge Nybegynder
21. november 2007 - 20:18 #3
Hej nielle,

Tak for dit meget fuldesgørende eksempel. Det er bare så stort.

Jeg har ikke styr over selve KUNDE eller REPORTER objekterne da det er resultater fra et webservice kald, men for at få en samlet KUNDE og X antal REPORTER ville jeg oprette en klasse som kunne håndtere disse og så XmlSerialize denne klasse.

En ting som jeg helt sikker ikke har med i min sObject klasse er en tom constructor så det vil jeg forsøge i morgen når jeg har adgang til webServicen igen :)

Jeg vender stærk tilbage :)

/Werge
Avatar billede nielle Nybegynder
21. november 2007 - 20:26 #4
KUNDE og REPORTER typerne skal være markeret som Serializable eller går den ikke. Der er nu en vis chance for at de er det siden at de kan streames over en webservice.
Avatar billede jesperwerge Nybegynder
21. november 2007 - 20:26 #5
Lige for at uddybe min løsning op til nu:

Jeg har 2 webservices der giver mig 1 KUNDE objekt og x antal REPORTER objekter

samtidig har jeg et List<sObject> som jeg tilføjer sObjects som består af KUNDE objectet og de antal af REPORTER objekter jeg nu får tilbage fra mine WebService kald.

Herefter er det min plan via XmlSerialize at få XML strukturen via en XmlWriter:

XmlSerializer oSerializer = new XmlSerializer(typeof(GlitnirConsole.StreamServeObject), extraTypes);

XmlWriterSettings xwSettings = new XmlWriterSettings();
xwSettings.OmitXmlDeclaration = true;
xwSettings.Indent = true;
xwSettings.Encoding = Encoding.UTF8;
xwSettings.ConformanceLevel = ConformanceLevel.Fragment;

XmlWriter xmlWriter = XmlWriter.Create(_filepath,xwSettings);
xmlWriter.WriteStartElement("CustomerReports");

foreach (sObject StrS in list)
{
  oSerializer.Serialize(xmlWriter, StrS, customNamespace);
}
xmlWriter.WriteEndElement();
xmlWriter.Close();
Avatar billede jesperwerge Nybegynder
21. november 2007 - 20:29 #6
det er jeg ret sikker på de er, mne ellers så bliver de det :) - desværre har jeg ingen direkte adgang til WebServicesne, men der skal vist ikke meget overtalelse til, hvis dette skal lykkes :)

Jeg vender tilbage

/Werge
Avatar billede jesperwerge Nybegynder
22. november 2007 - 07:41 #7
Hej nielle

jeg har forsøgt med dit forslag om en tom contructor, så min sObejct klasse ser således ud:


namespace GlitnirConsole
{
    [Serializable] 
    public class StreamServeObject
    {
        public StreamServeObject() { }

        public GlitnirCustomerWebService.Customer customer;
        public GlitnirReportWebService.PositionReport[] reportsArray;
  }
}
men får stadig samme fejl??

jeg kan godt få lov til at serialize KUNDER og REPORTER for sig, det er ikke noget problem, men jeg kan ikke gøre det med min sObject klasse :(

har du nogle forslag ?

/werge
Avatar billede jesperwerge Nybegynder
22. november 2007 - 16:12 #8
Hej nielle,

jeg har fundet en anden måde at løse min serialisering på, istedet for at lave min egen klasse der består af mine KUNDER og REPORTER, så serializer jeg dem on the fly.

kode:

foreach (cWebService.KUNDE c in custList)
  {
    Boolean ok = false;
    List<rWebService.PositionReport> reports = new List<rWebService.PositionReport>();
      foreach (cWebService.Portfolio p in c.Portfolios)
        {
          if (p.CustomerType.Equals(cWebService.PortfolioCustomerType.FUND))
            {
              ok = true;
              reports.Add(rWebServiceHandle.getPosReport("user",p.Id,DateTime.Now));
              Console.WriteLine(p.CustomerType.ToString());
            }
    }
  if (ok)
  {
      cSerializer.Serialize(xmlWriter, c, customNamespace);
      foreach (GlitnirReportWebService.PositionReport r in reports)
        {
            rSerializer.Serialize(xmlWriter, r, customNamespace);
        }
    }
}

det giver en samlet fil/memeryStream med alle nødvendige object som er serializeret. Det var ikke helt min ide - men det virker ret godt og stabilt.


Smid et svar så du kan få nogle point.

/werge
Avatar billede nielle Nybegynder
22. november 2007 - 17:56 #9
Nice.

Jeg vil da sige at jeg fik noget der lignede den fejl-besked du beskriver da jeg kodede mit eksempel. Svjh. forsvandt den med at jeg tilføjede den tomme constructor til Rapport-klassen. Men lige nu står mindet godt nok en smule svagt, så det kan være at det ikke lige var det...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester