Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

"Advanced" XML Serialization

Îåêßíçóå áðü ôï ìÝëïò kkara. Τελευταία δημοσίευση από το μέλος kkara στις 05-12-2005, 14:01. Υπάρχουν 4 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  23-11-2005, 15:26 7267

    "Advanced" XML Serialization

    Καιρό είχε να πέσει ερώτημα για Web Services οπότε είπα να αδράξω την ευκαιρία. Ξεκινάμε λοιπόν.
    Υλοποιώ αυτή την εποχή κάποια Web Services τα οποία θέλω να είναι όσο πιο interoperable γίνεται. Για το λόγο αυτό αποφάσισα να παρατηρώ το παραγόμενο WSDL για κάθε τι που ορίζω ότι λαμβάνουν ή επιστρέφουν τα Services. Μετά από πολύ ψάξιμο σχετικά με τον XMLSerializer, τα attributes που ελέγχουν το παραγόμενο WSDL και το XSD.exe, διαπίστωσα ότι κάποια απλά πράγματα δεν καταφέρνω να τα κάνω. Πιο συγκεκριμένα :
    • Ενώ κατάφερα να θέσω ότι ένα property τύπου int ή DateTime σε μια κλάση είναι προαιρετικό (χρησιμοποιώντας ένα bool property με όνομα <PropertyName>Specified), δεν κατάφερα να θέσω ότι ένα property τύπου string είναι υποχρεωτικό. Ότι και να κάνω πάντοτε στο παραγόμενο XSD ένα property τύπου string μπαίνει με minOccurs="0" (προφανώς για να υποστηρίζεται η null τιμή). Το ίδιο βέβαια συμβαίνει και για τις παραμέτρους μιας Web Method με αποτέλεσμα να μην μπορώ να απαιτήσω τιμή για μια παράμετρο τύπου string.
    • Επίσης δεν κατάφερα να θέσω Optional παραμέτρους σε Web Methods όταν πρόκειται για τύπο int, DateTime, custom enumerations, κτλ. Εκεί δηλαδή που θέλω να βάλω minOccurs="0" δεν τα καταφέρνω Sad [:(].Θα μπορούσα βέβαι να το πετύχω χρησιμοποιώντας κλάσεις ή structures ως input των WebMethods αλλά προσπαθώ να το αποφύγω.
    • Ιδίως όταν θέλω να κάνω κάτι πιο advanced, π.χ. να ορίσω ότι το string που δέχεται μια μέθοδος έχει συγκεκριμένο μήκος, δεν κατάφερα να βρω τρόπο.
    Γενικώς λοιπόν δεν κατάφερα να διαμορφώσω το XSD που περιέχεται στο WSDL ορίζοντας με κάποιο τρόπο τις κλάσεις και τις μεθόδους μου. Ομολογώ ότι δεν δοκίμασα να φτιάξω δικό μου XMLSerializer (και δεν είμαι και σίγουρος ότι κι αυτό θα βοηθήσει). Έχει κανείς καμιά ιδέα για το πως μπορούν να γίνουν τα παραπάνω; Ενδιαφέρον θα ήταν να υπήρχε ένα "AdvancedXSD.exe" το οποίο να δέχεται ένα XSD με πολύπλοκα definitions και να παρήγαγε τις κατάλληλες κλάσεις.

    Στερνή μου γνώση να σε είχα πρώτα...
  •  23-11-2005, 19:23 7277 σε απάντηση της 7267

    Απ: "Advanced" XML Serialization

    Όταν ο τύπος μιας παραμέτρου είναι ακέραιος, και η xml με τα δεδομένα σου περιέχει πχ: <Myparameter></MyParameter> βλέπεις ξεκάθαρα ότι δεν έχει μέσα κανέναν ακέραιο, άρα είναι null και άρα μπορείς να προσδιορίσεις αν μπορεί να είναι null ή όχι. Αν όμως για την ίδια παράμετρο ο τύπος ήταν string, πως θα μπορούσες μέσα στην xml με τα δεδομένα να ξεχωρίσεις το null από το empty string (string με μήκος 0); Άρα, αφού δεν γίνεται να τα ξεχωρίσεις δεν σε αφήνει και να το ορίσεις σαν required. Υποθέσεις κάνω.... χάνω λίγο σε βάθος στην xml...


    Χρήστος Γεωργακόπουλος
  •  24-11-2005, 10:03 7284 σε απάντηση της 7277

    Απ: &quot;Advanced&quot; XML Serialization

    Η ιδέα με την XML γενικώς είναι ότι όταν δεν υπάρχει καθόλου το element τότε θεωρείται null, ενώ όταν υπάρχει και δεν περιέχει τίποτα τότε είναι το κενό string. Για να θέσεις στο XSD ότι ένα element μπορεί να μην υπάρχει καθόλου τότε το ορίζεις ως π.χ.
    <s:element minoccurs="0" maxoccurs="1" name="MyParameter" type="s:string">
    Έτσι αν έχουμε ένα field MyParameter τύπου string τότε το <MyParameter></MyParameter> αντιστοιχεί στο String.Empty και όχι στο null. Αν το πεδίο ήταν τύπου int τότε θα υπήρχε πρόβλημα καθώς δεν θα πέρναγε το XSD Validation εφόσον δεν περιέχεται valid int τιμή.

    Αν δεν υπάρξει καμιά ιδέα θα βάλω σε επόμενο post κανένα workaround...
    Στερνή μου γνώση να σε είχα πρώτα...
  •  25-11-2005, 10:35 7314 σε απάντηση της 7267

    Απ: "Advanced" XML Serialization

    Τελικά το καλύτερο που μπόρεσα να κάνω για να φέρω το παραγόμενο WSDL μιας WebService στα "μέτρα" μου είναι να ανταλάσσω αντικείμενα κλάσεων που έχω φτιάξει για αυτό το σκοπό. Η ιδέα είναι να χρησιμοποιηθούν επιπλέον πεδία που θα ελέγχουν το παραγόμενο output όταν ο XMLSerializer κάνει serialize τα instances. Για παράδειγμα η κλάση :

    public class MyClass {
       public string
    MyString;
       public short
    MyShort;
       public
    DateTime MyDateTime;
    }

    παράγει το εξής XSD τμήμα :

    <s:complexType name="MyClass">
       <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="MyString" type="s:string" />
          <s:element minOccurs="1" maxOccurs="1" name="MyShort" type="s:short"
    />
          <s:element minOccurs="1" maxOccurs="1" name="MyDateTime" type="s:dateTime" />

       </s:sequence>
    </s:complexType>

    Όπως φαίνεται το πεδίο τύπου string είναι προαιρετικό, ενώ τα άλλα δύο πεδία είναι υποχρεωτικά. Παρότι δεν κατάφερα να κάνω το πρώτο πεδίο υποχρεωτικό, τουλάχιστον κατάφερα να κάνω τα άλλα δύο πεδία προαιρετικά, αλλάζοντας την κλάση ως εξής :

    public class MyClass {
       public string
    MyString;
       public short
    MyShort;
       public bool
    MyShortSpecified;
       [System.Xml.Serialization.XmlIgnoreAttribute()]
       public
    DateTime MyDateTime = DateTime.MinValue;
       [System.Xml.Serialization.XmlIgnoreAttribute()]
       public bool
    MyDateTimeSpecified {
          get { return this
    .MyDateTime != DateTime.MinValue; }
          set { this
    .MyDateTime = DateTime.MinValue; }
       }
    }

    Τα δύο πεδία που προστέθηκαν έχουν ονόματα ίδια με τα πεδία που θα γίνουν προαιρετικά με επιπλέον κατάληξη το Specified. Τα πεδία αυτά δεν περιλαμβάνονται στο Serialization λόγω του XmlIgnoreAttribute, αλλά όταν ο XMLSerializer κάνει serialize ένα instance της MyClass ελέγχει την τιμή τους και ανάλογα αποφασίζει αν θα βάλει το αντίστοιχο element στο XML ή όχι (δυστυχώς για το short δεν μπορεί να γίνει αυτόματα, όπως για το DateTime Sad [:(]). Έτσι το παραγόμενο WSDL είναι απλά :

    <s:complexType name="MyClass">
       <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="MyString" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="MyShort" type="s:short"
    />
          <s:element minOccurs="0" maxOccurs="1" name="MyDateTime" type="s:dateTime" />

       </s:sequence>
    </s:complexType>

    Αν λοιπόν σε μια WebMethod πρέπει να οριστούν κάποιοι παράμετροι εισόδου προαιρετικοί, ο τρόπος είναι να χρησιμοποιήσεις αντικείμενα ως input. Εξακολουθεί βέβαια να παραμένει το ερώτημα του πως θα κάνω το MyString υποχρεωτικό (ώστε να μην χρειάζεται να ελέγχω αν είναι null και να πετάω exceptions). Γενικώς πάντως το συμπέρασμα είναι ότι δεν μπορείς να έχεις απόλυτο έλεγχο του σχήματος που ακολουθούν τα αντικείμενα που ανταλάσσεις Sad [:(].


    Στερνή μου γνώση να σε είχα πρώτα...
  •  05-12-2005, 14:01 7568 σε απάντηση της 7314

    Απ: "Advanced" XML Serialization

    Επανέρχομαι (δριμύτερος;) για ένα επιπλέον ερώτημα σχετικά με το αυτόματα παραγόμενο WSDL. Ξέρει κανείς αν μπορώ να εισάγω με κάποιο τρόπο στο WSDL annotation για τα elements που δημιουργούνται; Σε ένα κανονικό XSD θα μπορούσα να περιγράψω ένα element ως π.χ. :

    <xs:element name="testElement">
       <xs:annotation>
          <xs:documentation>My annotation for testElement</xs:documentation>
       </xs:annotation>
    </xs:element>

    Μπορώ να κάνω κάτι αντίστοιχο σε ένα element που παράγεται αυτόματα στο WSDL (π.χ. element που αντιστοιχεί σε definition κλάσης, κτλ.);


    Στερνή μου γνώση να σε είχα πρώτα...
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems