Reputation: 779
I have a webservices and I've added it to my .NET project as a web reference. One of the web methods returns a nested array (NameValuePairDTOArray[NameValuePairDTO[]). I can only get null objects in .NET code, but it did return the data when I tested by SoapUI.
I pasted some part of the wsdl file here.
This is the method definition.
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://services.mymachine.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IneteractionService" targetNamespace="http://services.mymachine.com/">
<operation name="getValue" parameterOrder="parameters">
<input message="tns:MyServices_getValues"/>
<output message="tns:MyServices_getValuesResponse"/>
<fault message="tns:ServiceException" name="ServiceException"/>
</operation>
<xs:schema xmlns:ns1="http://ods.mymachine.com/v1_0_0" xmlns:tns="http://services.mymachine.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://services.mymachine.com/" version="1.0">
<xs:import namespace="http://ods.mymachine.com/v1_0_0"/>
<xs:element name="ServiceException" type="tns:ServiceException"/>
<xs:element name="getValue" type="tns:getValue"/>
<xs:element name="getValuesResponse" type="tns:getValuesResponse"/>
<xs:complexType name="getValue">
<xs:sequence>
<xs:element minOccurs="0" name="firstName" type="xs:string"/>
<xs:element minOccurs="0" name="lastName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="getValuesResponse">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="ns1:NameValuePairDTOArray"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</definitions>
This is the response data definitions.
<xs:schema xmlns:ns1="http://common.mymanchine.com/v1_0_0" xmlns:tns="http://ods.mymachine.com/v1_0_0" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://ods.mymachine.com/v1_0_0" version="1.0">
<xs:import namespace="http://common.mymanchine.com/v1_0_0"/>
<xs:complexType final="#all" name="NameValuePairDTOArray">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="tns:NameValuePairDTO"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="NameValuePairDTO">
<xs:complexContent>
<xs:extension base="ns1:DataTransferObject">
<xs:sequence/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="value" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema
The proxy classes generated by .NET are like:
[WebServiceBinding(Name = "InteractionServicesBinding", Namespace = "http://services.mymachine.com/")]
[XmlInclude(typeof(DataTransferObject))]
[DebuggerStepThrough]
[GeneratedCode("System.Web.Services", "4.0.30319.1")]
[DesignerCategory("code")]
public class InteractionServicesServiceWse : WebServicesClientProtocol
{
public InteractionServicesServiceWse();
[SoapDocumentMethod("", RequestNamespace = "http://services.mymachine.com/",
ResponseNamespace = "http://services.services.mymachine.com/", Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public NameValuePairDTOArray[] getValue(string firstName, string lastName);
}
[Serializable]
[XmlType(Namespace = "http://ods.mymachine.com/v1_0_0")]
[GeneratedCode("System.Xml", "4.0.30319.233")]
[DebuggerStepThrough]
[DesignerCategory("code")]
public class NameValuePairDTOArray
{
public NameValuePairDTOArray();
[XmlElement("item", IsNullable = true)]
public NameValuePairDTO[] item { get; set; }
}
[Serializable]
[DesignerCategory("code")]
[XmlType(Namespace = "http://ods.mymachine.com/v1_0_0")]
[GeneratedCode("System.Xml", "4.0.30319.233")]
[DebuggerStepThrough]
public class NameValuePairDTO : DataTransferObject
{
public NameValuePairDTO();
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string value { get; set; }
}
Now if I call getValue("John", "Peter"), it will return as below in .NET.
But the soapUI returns something like:
<env:Body>
<ns2:getValueResponse xmlns:ns2="http://services.mymachine.com/">
<return>
<item value="123" name="BONUS_ID"/>
<item value="456" name="POPUP_OBJECT_ID"/>
</return>
<return>
<item value="123" name="BONUS_ID"/>
<item value="567" name="POPUP_OBJECT_ID"/>
</return>
</ns2:getValueResponse>
</env:Body>
It seems that .NET cannot detect that NameValuePairDTO/item is an array.
What's wrong?
Upvotes: 1
Views: 550
Reputation: 779
Well, the issue turned out to be that something was wrong in the server side.
The schema defined that NameValuePairDTOArray and NameValuePairDTO were quailifed.
But look at the response xml,
<env:Body>
<ns2:getValueResponse xmlns:ns2="http://services.mymachine.com/">
<return>
<item value="123" name="BONUS_ID"/>
<item value="456" name="POPUP_OBJECT_ID"/>
</return>
<return>
<item value="123" name="BONUS_ID"/>
<item value="567" name="POPUP_OBJECT_ID"/>
</return>
</ns2:getValueResponse>
The return(NameValuePairDTOArray) and item(NameValuePairDTO) are unqualified. And the proxy class generated assumes that they are qualified because schema defined, but this caused the failure to parse the xml.
The quick fix will be to manually add the unqualifed attribute to the NameValuePairDTO property in NameValuePairDTOArray class.In the future, the serve side should fix this issue.
Upvotes: 2
Reputation: 9389
Your NameValuePairDTOArray in the generated code appears with the namespace "http://ods.mymachine.com/v1_0_0" but this namespace is not in the xml ouput (so .net doesn't know that the tag "return" refers to a NameValuePairDTOArray).
Maybe you removed the XmlTypeAttribute from the server's code.
So you should either : refresh your web reference on the client side or add back the XmlTypeAttribute on the server side.
Upvotes: 1