Bugzilla – Bug 670945
XML Serialization output differs from Microsoft .NET Runtime (or CLR)
Last modified: 2011-05-09 06:25:29 UTC
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7 Hi, I'm using a generated ServiceModel.ClientBase<> implementation, generated by ONVIF WSDL documents (e.g.: DdviceManagement.wsdl) found on onvif.org (though web references). I found out that when serializing an array of enum values, the output differs when using the Mono 2.8.2 runtime compared to the Microsoft .NET runtime. Because of this difference, the remote web service doesn't understand the request and responds with a "400 - Bad Request" message. However, when I do a manual serialization of instances of the problematic class (using an XmlSerializer and StringWriter), the serialized XML output is the same whether I use the Mono 2.8.2 or Microsoft .NET runtimes. So it seems that the problem deep within the ServiceModel web services client classes that perform XML serialization under the hood. The problem is related to the serialization of an array of enum values. See the actual and expected results. Reproducible: Always Steps to Reproduce: 1. Create a console app project, and add the following Web Reference to your project: http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl 2. Instantiate a DeviceClient object, with an HTTP basic binding, and an endpoint. 3. Invoke the 'GetCapabilities(CapabilityCategory[]) method. 4. Check the XML request message that is output. Actual Results: <?xml version="1.0" encoding="utf-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <GetCapabilities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.onvif.org/ver10/device/wsdl"> <Category> <CapabilityCategory>All</CapabilityCategory> </Category> </GetCapabilities> </s:Body> </s:Envelope> Expected Results: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <GetCapabilities xmlns="http://www.onvif.org/ver10/device/wsdl"> <Category>All</Category> </GetCapabilities> </s:Body> </s:Envelope> The difference (apart from the XML header) is that the CapabilityCategory element should not be there in the actual result. The CapabilityCategory name is in fact the name of the enumeration from which 'All' is from. See the declarations: public partial class GetCapabilitiesRequest { ... [System.Xml.Serialization.XmlElementAttribute("Category")] public CapabilityCategory[] Category; ... } public enum CapabilityCategory { All, ... }
If you need me for whatever support, know that I'm available. Thank you for your time and support, Charles
Our WsdlImporter cannot generate valid client proxy and it is not practical without fixing this issue. So first I'm going to fix it. So far I got simple repro for the importer issue: ---- 670945.cs ---- using System; using System.Collections; using System.IO; using System.ServiceModel; using System.ServiceModel.Description; using System.Xml; using System.Xml.Schema; using WSServiceDescription = System.Web.Services.Description.ServiceDescription; public class Imp { public static void Main (string [] args) { var mset = new MetadataSet (); WSServiceDescription sd = null; sd = WSServiceDescription.Read (XmlReader.Create ("670945.wsdl")); mset.MetadataSections.Add (new MetadataSection () { Dialect = MetadataSection.ServiceDescriptionDialect, Metadata = sd }); var imp = new WsdlImporter (mset); var sec = imp.ImportAllContracts (); } } ---- 670945.wsdl ---- <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" targetNamespace="http://www.onvif.org/ver10/device/wsdl"> <wsdl:types> <xs:schema targetNamespace="http://www.onvif.org/ver10/schema" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema"> <xs:complexType name="SystemDateTime"> <xs:sequence> <xs:element name="foobar" type="xs:string" minOccurs="0" /> <xs:element name="Extension" type="tt:SystemDateTimeExtension" minOccurs="0"/> </xs:sequence> <!-- xs:anyAttribute processContents="lax"/ --> </xs:complexType> <xs:complexType name="SystemDateTimeExtension"> <xs:sequence> <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:schema> <xs:schema targetNamespace="http://www.onvif.org/ver10/device/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" elementFormDefault="qualified"> <xs:element name="GetSystemDateAndTime"> <xs:complexType> <xs:sequence/> </xs:complexType> </xs:element> <xs:element name="GetSystemDateAndTimeResponse"> <xs:complexType> <xs:sequence> <xs:element name="SystemDateAndTime" type="tt:SystemDateTime"> <xs:annotation> <xs:documentation>Contains information whether system date and time are set manually or by NTP, daylight savings is on or off, time zone in POSIX 1003.1 format and system date and time in UTC and also local system date and time.</xs:documentation> </xs:annotation> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> <wsdl:message name="GetSystemDateAndTimeRequest"> <wsdl:part name="parameters" element="tds:GetSystemDateAndTime"/> </wsdl:message> <wsdl:message name="GetSystemDateAndTimeResponse"> <wsdl:part name="parameters" element="tds:GetSystemDateAndTimeResponse"/> </wsdl:message> <wsdl:portType name="Device"> <wsdl:operation name="GetSystemDateAndTime"> <wsdl:documentation>This operation gets the device system date and time. The device shall support the return of the daylight saving setting and of the manual system date and time (if applicable) or indication of NTP time (if applicable) through the GetSystemDateAndTime command.<br/> A device shall provide the UTCDateTime information.</wsdl:documentation> <wsdl:input message="tds:GetSystemDateAndTimeRequest"/> <wsdl:output message="tds:GetSystemDateAndTimeResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="DeviceBinding" type="tds:Device"> <wsdl:operation name="GetSystemDateAndTime"> <soap:operation soapAction="http://www.onvif.org/ver10/device/wsdl/GetSystemDateAndTime"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> </wsdl:definitions>