Monday, April 16, 2007

WCF - Getting something like: 'EndElement' 'request' from namespace '...' is not expected. Expecting element '...'. ?

That was the tricky one at the start of the learning curve. Our problem mostly was that developers are quite often tempted to complete WCF software factory wizards as fast possible. That leads to the possibility that on one side it is XmlSerializer that is used and on the server side it is DataContractSerializer. If you are tracking down something like this here is the sample from the message log for the client side XmlSerializer: <InsertBusinessUnitCommon xmlns="http://DQV.Apps.Client.Setup.WebServices.ServiceContracts/2007/03"> <request> <CreateDate xsi:nil="true"></CreateDate> <UpdateDate xsi:nil="true"></UpdateDate> <VersionNumber xsi:nil="true"></VersionNumber> <EntityStatus>None</EntityStatus> <BusinessUnitSid>0</BusinessUnitSid> <MarketSegmentSid>0</MarketSegmentSid> <BusinessUnitName>TestName</BusinessUnitName> <BusinessUnitAliasName>Test</BusinessUnitAliasName> <EffectiveDate>2007-04-16T22:17:30.179159+01:00</EffectiveDate> <EndDate xsi:nil="true"></EndDate><StreetAddress2>Test Address 2</StreetAddress2> <City>New York</City> <StateProvince>NY</StateProvince> <ZipCode>10001</ZipCode> <CountryCode>US</CountryCode> </request> </InsertBusinessUnitCommon> On the other side when you use DataContractSerializer you are sending to the server in the same case: <InsertBusinessUnitCommon xmlns="http://DQV.Apps.Client.Setup.WebServices.ServiceContracts/2007/03"> <request xmlns:a="http://DQV.Apps.Client.Setup.WebServices.DataContracts/2007/03" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:CreateDate>2007-04-16T22:41:50.8856166+01:00</a:CreateDate> <a:CreateProgram>test</a:CreateProgram> <a:CreateUser i:nil="true"></a:CreateUser> <a:EntityStatus>None</a:EntityStatus> <a:UpdateDate i:nil="true"></a:UpdateDate> <a:UpdateProgram i:nil="true"></a:UpdateProgram> <a:UpdateUser i:nil="true"></a:UpdateUser> <a:VersionNumber i:nil="true"></a:VersionNumber> <a:BusinessUnitAliasName>Test</a:BusinessUnitAliasName> <a:BusinessUnitId i:nil="true"></a:BusinessUnitId> <a:BusinessUnitName>TestName</a:BusinessUnitName> <a:BusinessUnitSid>0</a:BusinessUnitSid> <a:City>New York</a:City> <a:CountryCode>US</a:CountryCode> <a:County i:nil="true"></a:County> <a:EffectiveDate>2007-04-16T22:41:50.8856166+01:00</a:EffectiveDate> <a:EndDate i:nil="true"></a:EndDate> <a:FaxNumber i:nil="true"></a:FaxNumber> <a:MarketSegmentSid>0</a:MarketSegmentSid> <a:PhoneExtension i:nil="true"></a:PhoneExtension> <a:PhoneNumber i:nil="true"></a:PhoneNumber> <a:SchemaName i:nil="true"></a:SchemaName> <a:StateProvince>NY</a:StateProvince> <a:StreetAddress1 i:nil="true"></a:StreetAddress1> <a:StreetAddress2>Test Address 2</a:StreetAddress2> <a:StreetAddress3 i:nil="true"></a:StreetAddress3> <a:ZipCode>10001</a:ZipCode> </request> </InsertBusinessUnitCommon> Difference is so obvious and given understanding of limited DataContractSerialization flexibility, strict ordering of fields, it is obvious that XmlSerializer would rarely have a chance to generate the DataContractSerializer matching/compatible xml. Imagine it worked for some ... It better be broken :). Solution for this problem is setting up either XmlSerializer or DataContractSerializer on both sides. Of course, your problem can be different ...

No comments: