Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Web servisi i serijalizacija

[es] :: .NET :: ASP.NET :: Web servisi i serijalizacija

[ Pregleda: 1689 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

giger
Beograd

Član broj: 31688
Poruke: 172
91.148.94.*



Profil

icon Web servisi i serijalizacija18.08.2008. u 23:10 - pre 190 meseci
Evo ovako pravim neki servis cije bi sve metode vracale ovu klasu

Code:

[XmlRoot(ElementName = "OperationStatus")]
    public class OperationStatus
    {
        private string _statusCode;
        private string _statusMessage;
        private object _object;

        [XmlElement]
        public string StatusCode
        {
            get
            {
                return _statusCode;
            }
            set
            {
                _statusCode = value;
            }
        }

        [XmlElement]
        public string StatusMessage
        {
            get
            {
                return _statusMessage;
            }
            set
            {
                _statusMessage = value;
            }
        }

        [XmlElement(ElementName = "Result")]
        public object Object
        {
            get
            {
                return _object;
            }
            set
            {
                _object = value;
            }
        }
    }


Zamislio sam da u ovaj "Object" (Result) stavljam svoje objekte . To mogu biti prosti tipovi, ili klase ili pak kompleksne klase.

Medjutim naisao sam na problem, ako KLASA_A sadrzi ArrayList objekata klase KLASA_B, tada dobijam ovu gresku:

Citat:

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidCastException: Unable to cast object of type 'KLASA_A' to type 'KLASA_B'.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write1_Object(String n, String ns, Object o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write5_OperationStatus(String n, String ns, OperationStatus o, Boolean isNullable, Boolean needType)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write10_OperationStatus(Object o)
at Microsoft.Xml.Serialization.GeneratedAssembly.OperationStatusSerializer4.Serialize(Object objectToSerialize, XmlSerializationWriter writer)
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
--- End of inner exception stack trace ---
at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
at System.Xml.Serialization.XmlSerializer.Serialize(TextWriter textWriter, Object o)
at System.Web.Services.Protocols.XmlReturnWriter.Write(HttpResponse response, Stream outputStream, Object returnValue)
at System.Web.Services.Protocols.HttpServerProtocol.WriteReturns(Object[] returnValues, Stream outputStream)
at System.Web.Services.Protocols.WebServiceHandler.WriteReturns(Object[] returnValues)
at System.Web.Services.Protocols.WebServiceHandler.Invoke()



Jel ima neko ideju, jel radio neko nesto slicno?

Hvala unapred,
pozdrav
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Web servisi i serijalizacija19.08.2008. u 12:39 - pre 190 meseci
Za pocetak, dva saveta:

- nemoj imenovati identifikatore rezervisanim recima i imenima drugih tipova tako sto ces promeniti case. C# jeste case sensitive, ali CLR nije, prizivas sebi probleme. Umesto Object, stavi InnerObject ili nesto slicno.
- ako koristis C#3.0 ne treba ti poseban storage za propertije koji imaju set i get koji samo citaju i pisu iz tog storage-a. Umesto

Code:

        private string _statusCode;

        [XmlElement]
        public string StatusCode
        {
            get
            {
                return _statusCode;
            }
            set
            {
                _statusCode = value;
            }
        }


dovoljno je da napises

Code:

        [XmlElement]
        public string StatusCode { get; set; }


a kompajler ce sam rezervisati private storage i napraviti get i set accessore.


Sto se tice greske, dobijas je pri serijalizaciji Object propertija. Nije mi bas najjasnije zasto serijalizer pokusava da castuje A u B, ajd okaci relevantne delove KLASA_A i KLASA_B. ONo sto je sigurno je da je serijalizacija kaskadna, sto ce reci sve instance koje se nalaze u drvu objekta moraju biti serializable.


Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

giger
Beograd

Član broj: 31688
Poruke: 172
*.kc.vicert.com.



Profil

icon Re: Web servisi i serijalizacija19.08.2008. u 14:06 - pre 190 meseci
Pozdrav i hvala ti

U pravu si za imenovanje, promenio sam u InnerObject, a sto se tice ovog ostalog, nisam znao za tu sintaksu, ali i radim na .NET 2.0 tako da ....

Da se sad vratim na problem serijalizacije...

Ovako sam definisao klase:
Code:

public class KLASA_A
    {
    private ArrayList _klasaBList

       [XmlArray( KLASA_B_List), XmlArrayItem("KLASA_B", typeof(KLASA_B))]
        public ArrayList KLASA_B_List
        {
            get
            {
                return _klasaBList
            }
            set
            {
                _klasaBList = value;
            }
        }
     }


public class KLASA_B
    {
    private int id;

    [XmlElement]
        public int ID
        {
            get
            {
                return id;
            }
            set
            {
                id;= value;
            }
        }
    }   


E, sad problem je kad hocu u InnerObject da vratim samo ArrayList od objekata KLASA_A, tad imam probleme, a kad koristim sledecu klasu ciji objekat postavim u InnerObject, tad sve radi:

Code:

[XmlRoot("KLASA_A_LIST_Result")]
    public class KLASA_A_LIST
    {
        private ArrayList _klasaAList

        public KLASA_A_LIST()
        {
            _klasaAList= new ArrayList();
        }

        [XmlArray("KLASA_A_LIST"), XmlArrayItem("KLASA_A", typeof(KLASA_A))]
        public ArrayList [XmlArray("KLASA_A_LIST"),
        {
            get
            {
                return _klasaAList
            }
            set
            {
                _klasaAList= value;
            }
        }
    }


..., ali dobijem visak xml tagova u rezultatu

nesto ovako

Code:

<Result xsi:type="KLASA_A_LIST">
    <KLASA_A_LIST> <-- Ovaj mi je tag visak i on me nervira
        <...ovde je lista objekata tipa KLASA_A, sa ugnjezdenim kolekcijama KLASA_B>
    <KLASA_A_LIST>
</Result>




Samo da napomenem da na onoj OperationStatus klasi imam i ovaj atribut, koji je potreban da bi ovo ovako radilo:

Code:

[XmlInclude(typeof(KLASA_A_LIST))]


A, mozda ne razumem problematiku dovoljno, mozda i ne moze drugacije, nego ovako kako sam izveo...???
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: Web servisi i serijalizacija19.08.2008. u 17:56 - pre 190 meseci
Pa, mislim da ne moze drugacije pod ovim okolnostima. ArrayList je untyped niz, pa kad serijalizujes u XML serijalizer ne zna sta je u njemu. Iz tog razloga koristis XmlArray i XmlArrayItem atribute za B listu unutar A objekta (cime si u WSDLu kreirao complex type ArrayOfKLASA_B), medjutim kad imas instancu A liste nemas nigde deklarisano kakav je to Xml niz i iz cega se sastoji niti postoji nacin da to definises preko XmlInclude, samim tim serijalizacija puca (doduse greska je malo van mozga, a uzrok je to sto web servis pokusava da "spase stvar" i taj niz pretoci u onaj za koji ima WSDL contract, a to je ArrayOfKLASA_B, pokusvajuci da castuje).

Sto ne razlmislis o upotrebi tipiziranih nizova ili Collection<T> genericsa (ako ti treba dinamicka kontrol niza) i onda dodas

Code:

        [XmlInclude(typeof(KLASA_A[]))]                    // za  tipizirani niz

// ili

        [XmlInclude(typeof(Collection<KLASA_A>))]     // za generics


pred web metod ili pred OperationStatus klasu i dobices ono sto trazis, u WSDLu ce biti kreiran ArrayOfKLASA_A i niz/kolekcija ce biti serijalizovan bez uokvirujuceg taga.

Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

giger
Beograd

Član broj: 31688
Poruke: 172
91.148.94.*



Profil

icon Re: Web servisi i serijalizacija19.08.2008. u 19:22 - pre 190 meseci
Svaka cast, koji si car... Evo uspelo je. Hvala i na pojasnjenjima...


PS. Znam da si mi nesto dosta pomagao i pre oko godinu i po dana...

Puno hvala
 
Odgovor na temu

[es] :: .NET :: ASP.NET :: Web servisi i serijalizacija

[ Pregleda: 1689 | Odgovora: 4 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.