Τελικά το καλύτερο που μπόρεσα να κάνω για να φέρω το παραγόμενο 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
). Έτσι το παραγόμενο 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). Γενικώς πάντως το συμπέρασμα είναι ότι δεν μπορείς να έχεις απόλυτο έλεγχο του σχήματος που ακολουθούν τα αντικείμενα που ανταλάσσεις
.
Στερνή μου γνώση να σε είχα πρώτα...