Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContractSerializer and deserializing web service response types

I am using calling web services and using WCF generated service-reference on the client. I have saved XML responses that are received from test service to disk (without SOAP envelope and body tags) I would like to load them from disk and create objects from them. Lets' take the following method from my web service:

SomeMethodResponse SomeMethod(SomeMethodRequest req)

I manually (through SOAP UI) save the response to disk to file, Sample response:

<SomeMethodResponse xmlns="http://myNamespace">
    <SomeMember1>value</SomeMember1>
</SomeMethodResponse>

Then I try to deserialize the object from file using:

DataContractSerializer dcs = 
  new DataContractSerializer(typeof(SomeMethodResponse))

This fails – the serializer complains with the error, that it is expecting element in namespace 'http://schemas.datacontract.org/2004/07', but found element in 'http://myNamespace'.

Question: Why does the DataContractSerializer not use the namespace, that is declared on SomeMethodResponseType with XmlTypeAttribute(Namespace="http://myNamespace")?

I can work around this by explicitly providing the namespace and the root element to DataContractSerializer constructor. But then it fails with message similar to:

Error in line X position Y (last line of the XMLdocument). 'EndElement' 'SomeMethodResponse
from namespace 'httpmyNapespace’ is not expected. Expecting element 'someNameField'.

SomeName is an element in the XSD that web service is using. It is also a property on the SomeMethodResponse type, backed by the private field called someNameField. It looks like DataContractSerializer is trying to deserialize the fields in addition to properties.

How can I deserailize XML that I have saved from disk and get back the object of same type that SomeMethod is returning?

Thanks, Matra

like image 478
matra Avatar asked Dec 28 '22 22:12

matra


2 Answers

Your XML response clearly has a XML namespace:

<SomeMethodResponse xmlns="http://myNamespace">
    <SomeMember1>value</SomeMember1>
</SomeMethodResponse xmlns="http://myNamespace">

so in order to properly read and deserialize this, you need to tell your DataContractSerializer about this namespace:

DataContractSerializer dcs = 
    new DataContractSerializer(typeof(SomeMethodResponse),
                               "SomeMethodResponse", "http://myNamespace")

By specifying this default XML namespace in the constructor, it should be able to read and deserialize this XML now.

The other error you're getting:

Error in line X position Y (last line of the XMLdocument). 'EndElement' 'SomeMethodResponse from namespace 'httpmyNapespace’ is not expected. Expecting element 'someNameField'.

is caused by the very unusual and never before seen fact that your end element has a namespace on it........

</SomeMethodResponse xmlns="http://myNamespace">

just remove that extra unnecessary namespace, and you should be fine!

</SomeMethodResponse>
like image 159
marc_s Avatar answered Feb 15 '23 20:02

marc_s


Let me answer my own question: The cause of the second error mesasge is that actually, the svcUtil have silently chosen to use XmlSerializer insted of DataContractSerializer. I've found this by reading the help of XmlTypeAttribute- The MSDn states Controls the XML schema that is generated when the attribute target is serialized by the XmlSerializer. ;-) So we are back to old, XmlSerializer

like image 30
matra Avatar answered Feb 15 '23 20:02

matra