Reputation: 5231
I am trying to use a 3rd party webservice. One of the fields that is returned is defined as
<s:element name="SomeField" minOccurs="0" maxOccurs="1" type="s:int"/>
In the SOAP response they send the field as
<SomeField/>
This is causes the .Net deserializer to throw an exception as the empty xml element is not a valid integer.
What is the best way to handle this?
I have tried tweaking the wsdl to mark the field as nullable which does marked the generated fields as int? but the deserializer still fails.
I can implement the endpoint as either a service reference or as a web service reference.
Upvotes: 2
Views: 4230
Reputation: 161773
This is a bug in their code. That does not match the schema. XMLSpy says:
File Untitled6.xml is not valid.
Value '' is not allowed for element <SomeField>.
Hint: A valid value would be '0'.
Error location: root / SomeField
Details
cvc-datatype-valid.1.2.1: For type definition 'xs:int' the string '' does not match a literal in the lexical space of built-in type definition 'xs:int'.
cvc-simple-type.1: For type definition 'xs:int' the string '' is not valid.
cvc-type.3.1.3: The normalized value '' is not valid with respect to the type definition 'xs:int'.
cvc-elt.5.2.1: The element <SomeField> is not valid with respect to the actual type definition 'xs:int'.
I got that with the following schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root">
<xs:annotation>
<xs:documentation>Comment describing your root element</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="SomeField" minOccurs="0" maxOccurs="1" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
and the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xsi:noNamespaceSchemaLocation="Untitled5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SomeField/>
</root>
Upvotes: 1
Reputation: 35477
I don't think the .Net deserialiser can cope with this.
How about tweaking the definition of SomeField
to a string. This way can check for a null, but you would have to do an Int32.Parse to the real value.
<s:element name="SomeField" minOccurs="0" maxOccurs="1" type="s:string"/>
The accessor could be:
void int? GetSomeField()
{
if (someField == null) return null;
return In32.Parse(someField);
}
Upvotes: 4
Reputation: 65361
You could set the default to 0. That way if the value is not set it will send 0.
<s:element name="SomeField" minOccurs="0" maxOccurs="1" default="0" type="s:int"/>
Upvotes: 3