I am writing an ios app that talks to the asp.net server by using SOAP web services. one of my web service need to take array of objects. The object definitions are exactly the same on both sides.
Here is what I tried: When I passed just one object as the parameter, the web service worked fine. But as soon as I passed an array of the objects, I got nothing returned. I know the code inside the web service never get called which means the server failed to read the parameters. The wired thing is that the web service returned nothing so I cannot tell what's wrong(I used to get error message from server showing me the stack trace when I did something wrong in the past).
I am not that familiar with SOAP web services so even though I spent a lot of time on MSDN, I still didn't understand what's wrong. After publish the web service, I accessed it through browser. I copied the whole thing to my iOS app so it should work in theory but it never did.
Anyway, this is the server side code:
[System.Web.Services.Protocols.SoapRPCMethod]
[WebMethod(EnableSession = true)]
[XMLInclude(typeof(Team))]
[XMLInclude(typeof(Team[]))]
[SoapInclude(typeof(Team))]
[SoapInclude(typeof(Team[]))]
public string testTeamWebService(Team[] teams)
{
// do something here
}
// class definition of Team
[Serializable]
public class Team
{
public int TeamID;
public string TeamName;
}
According to the web service page(.asmx file), here is what I should do to call it:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="https://abc.com/" xmlns:types="https://abc.com/encodedTypes" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:testTeamWebService>
<teams href="#id1" />
</tns:testTeamWebService>
<soapenc:Array id="id1" soapenc:arrayType="types:Team[2]">
<Item href="#id2" />
<Item href="#id3" />
</soapenc:Array>
<types:Team id="id2" xsi:type="types:Team">
<TeamID xsi:type="xsd:int">int</TeamID>
<TeamName xsi:type="xsd:string">string</TeamName>
</types:Team>
<types:Team id="id3" xsi:type="types:Team">
<TeamID xsi:type="xsd:int">int</TeamID>
<TeamName xsi:type="xsd:string">string</TeamName>
</types:Team>
</soap:Body>
</soap:Envelope>
As I said, I constructed the xml and send it in iOS. I used NSMutableURLRequest object and the constructed xml is exactly the way I mentioned above.
In my other web services, I get object arrays from the server so I know .net can serialize the array. This is the first time that my service need to take an array as a parameter, so I think there must be a way of doing it.
Thanks for your reading and please give me some advice if you can.
I finally got the error message from server:
faultcode: soap:Server
faultstring: System.Web.Services.Protocols.SoapException: Server was unable to process request.---> System.ArgumentException: Object of type 'System.Xml.XmlNode[]' cannot be converted to type 'abc.WebServices.Team[]'.
at System.RuntimeType.CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Web.Services.Protocols.LogicalMethodInfo.Invoke(Object target, Object[] values)
at System.Web.Services.Protocols.WebServiceHandler.Invoke()
--- End of inner exception stack trace ---
detail: