[ Team LiB ] |
9.4 SOAP SerializationThere's another form of XML serialization, which may seem redundant at first. You'll recall that runtime serialization was able to encode an object using SOAP. The SoapFormatter produced a SOAP stream that was optimized for recreating the original object in another .NET application; specifically, the object and all its members were encoded using CLR types. A non-.NET application reading that SOAP stream would most likely have no idea what to do with the data. However, the XmlSerializer can also serialize an object to SOAP, with an emphasis on the standard SOAP encodings. With SOAP serialization, you get all the interoperability of XML, with additional CLR awareness. The key to standards-compliant SOAP serialization is the SoapReflectionImporter class. The .NET Framework SDK Documentation will tell you that SoapReflectionImporter is reserved for internal use, and should not be used by your application. However, it does have one constructor and one method that you can use to serialize objects to SOAP. The code in Example 9-9 demonstrates how to serialize the personnel records from earlier examples to SOAP, using the same Personnel class and the CreatePersonnel( ) method from before. Example 9-9. Serializing personnel records to SOAPpublic static void Main(string [ ] args) { Personnel personnel = CreatePersonnel( ); SoapReflectionImporter importer = new SoapReflectionImporter( ); XmlTypeMapping mapping = importer.ImportTypeMapping(typeof(Personnel)); XmlSerializer serializer = new XmlSerializer(mapping); using (StreamWriter stream = File.CreateText("PersonnelSoap2.xml")) { XmlTextWriter writer = new XmlTextWriter(stream); writer.Formatting = Formatting.Indented; writer.WriteStartElement("AngusHardware"); serializer.Serialize(writer,personnel); writer.WriteEndElement( ); } } The object will be serialized to the XML shown below: <AngusHardware> <Personnel xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/ 2001/XMLSchema-instance" id="id1"> <Employees href="#id2" /> </Personnel> <q1:Array id="id2" q1:arrayType="Employee[1]" xmlns:q1="http://schemas.xmlsoap.org/ soap/encoding/"> <Item href="#id3" /> </q1:Array> <Employee id="id3" d2p1:type="Employee" xmlns:d2p1="http://www.w3.org/2001/XMLSchema- instance"> <FirstName xmlns:q2="http://www.w3.org/2001/XMLSchema" d2p1:type="q2:string"> Niel</FirstName> <MiddleInitial xmlns:q3="http://www.w3.org/2001/XMLSchema" d2p1:type="q3:string" >M</MiddleInitial> <LastName xmlns:q4="http://www.w3.org/2001/XMLSchema" d2p1:type="q4:string" >Bornstein</LastName> <Addresses href="#id4" /> <HireDate xmlns:q5="http://www.w3.org/2001/XMLSchema" d2p1:type="q5:dateTime"> 2001-01-01T00:00:00.0000000-05:00</HireDate> </Employee> <q6:Array id="id4" q6:arrayType="Address[1]" xmlns:q6="http://schemas.xmlsoap.org/ soap/encoding/"> <Item href="#id5" /> </q6:Array> <Address id="id5" d2p1:type="Address" xmlns:d2p1="http://www.w3.org/2001/XMLSchema- instance"> <AddressType d2p1:type="AddressType">Home</AddressType> <Street href="#id6" /> <City xmlns:q7="http://www.w3.org/2001/XMLSchema" d2p1:type="q7:string" >Atlanta</City> <State d2p1:type="State">GA</State> <Zip xmlns:q8="http://www.w3.org/2001/XMLSchema" d2p1:type="q8:string">30037 </Zip> </Address> <q9:Array id="id6" xmlns:q10="http://www.w3.org/2001/XMLSchema" q9:arrayType="q10: string[1]" xmlns:q9="http://schemas.xmlsoap.org/soap/encoding/"> <Item>999 Wilford Trace</Item> </q9:Array> </AngusHardware> That's not very pretty. Fortunately, just as there are attributes that affect the serialization of an object to XML, there are attributes that affect the serialization of an object to SOAP. Table 9-3 lists them, with their descriptions.
Just as with XML attributes, you can override the SOAP attributes that affect serialization at runtime. To make the Personnel object serialize a little more sensibly, you can either add the attributes to the Personnel type's source code, or you can add them using the SoapAttributeOverrides class. The use of SoapAttributeOverrides is similar to XmlAttributeOverrides. Rather than go into extreme detail, I'll just show you the code, again with the changes highlighted: Personnel personnel = CreatePersonnel( ); SoapAttributeOverrides overrides = new SoapAttributeOverrides( ); SoapAttributes attributes = new SoapAttributes( ); attributes.SoapElement = new SoapElementAttribute("employees"); overrides.Add(typeof(Personnel), "Employees", attributes); SoapReflectionImporter importer = new SoapReflectionImporter(overrides); XmlTypeMapping mapping = importer.ImportTypeMapping(typeof(Personnel)); XmlSerializer serializer = new XmlSerializer(mapping); using (StreamWriter stream = File.CreateText("PersonnelSoap2.xml")) { XmlTextWriter writer = new XmlTextWriter(stream); writer.Formatting = Formatting.Indented; writer.WriteStartElement("AngusHardware"); serializer.Serialize(writer,personnel); writer.WriteEndElement( ); } The only changes effected by the SoapAttributeOverrides in this example is to change the name of the Employees element to employees, as shown here: <AngusHardware> <Personnel xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/ 2001/XMLSchema-instance" id="id1"> <employees href="#id2" /> </Personnel> ... </AngusHardware> |
[ Team LiB ] |