6
votes

Apparently this is a fairly often experienced issue. I'm not sure entirely where the problem lies, or what needs to be adjusted, but for the life of me I cannot retrieve anything other than a NULL result to my SoapObject or SoapPrimitive from my .NET XML web service with parameters.

I've tried everything I've found on the net:

  • Adding the .setXmlVersionTag = no change
  • Using SoapObject instead of SoapPrimitive = no change
  • Using SoapPrimitive instead of SoapObject = no change
  • Using HttpTransportSE instead of AndroidHttppTransport = no change
  • Using AndroidHttpTransport instead of HttpTransportSE = no change
  • Setting .dotNet = true = no change
  • Removing .dotNet assignment line = no change
  • Removing the colon (entire HTTP:// prefix) from the web service = no change
  • Using the PropertyInfo class instead of direct assignment = no change
  • Using direct assignment instead of the PropertyInfo class = no change

I'm at a total loss and it's quite frustrating. I have total control of the web service (I wrote it) so minor changes, if helpful, I'm willing to attempt.

Currently my code as follows is this:

public void GetResults()
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("lastName", "sm");
request.addProperty("middleName", "");
request.addProperty("firstName", "");
request.addProperty("pageSize", 25);
request.addProperty("pageNumber", 1);

SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);           
soapEnvelope.dotNet = true;
soapEnvelope.setOutputSoapObject(request);

//AndroidHttpTransport aht = new AndroidHttpTransport(URL);
HttpTransportSE aht = new HttpTransportSE(URL);

try
{
    aht.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    aht.call(SOAP_ACTION, soapEnvelope);           

    //SoapObject result = (SoapObject)soapEnvelope.bodyIn;
    SoapObject result = (SoapObject)soapEnvelope.getResponse();
    //SoapPrimitive result = (SoapPrimitive) soapEnvelope.getResponse();
    //Object result = soapEnvelope.getResponse();

    Log.d("WS", String.valueOf(result));          
}
catch(Exception e)
{
    e.printStackTrace();
}       
}

and my globals look like this:

private static final String SOAP_ACTION = "http://yoda/SearchPerson";
private static final String METHOD_NAME = "SearchPerson";
private static final String NAMESPACE = "http://yoda/";
private static final String URL = "http://yoda/ws.asmx";

I know 'yoda' is translating correctly as my non-parameterized web serivce is working like a bloody champ. (Everything is identical save the 'request.addProperty' calls which are obviously (part or all) of the issue at hand.)

If it matters I'm writing this against a 1.6 target platform with KSoap2 2.5.2 and it behaves identically across all my different Android emulators.

I've sniffed the packets with wireshark and the emulator appears to be sending the correct stuff but the results it receives are always NULL. (I've tested these exact parameters many times against my test web site that uses these web services, and all is working perfectly there.)

So, can anyone throw me a bone here?

Thanks,

Magua

EDIT 2010.11.28:

Even though Wireshark is telling me that I'm sending the parameters it would seem that the web service isn't receiving them correctly, or something similar. I created a whole new service that was suppose to return a simple string, whatever the first parameter was, with " TEST" at the end, hardcoded from the web service itself.

Well, every time I run this (from Android) I do get a result, and it is always " TEST". No matter how I formulate the SoapEnvelope or no matter what I pass as the parameter, I always receive " TEST". Of course when I invoke the web service on the server it works like a champ (and my result is "THIS IS A TEST").

My web service is on Windows Server 2008 with IIS 7. The application pool is running against framework v2.0 (not v4.0) with 'Integrated' managed pipeline mode.

I have no idea where the disconnect lies. Is KSoap2 sending the parameters improperly? Is IIS configured incorrectly? Something else entirely?

5

5 Answers

8
votes

Wow. Chalk this one up to all sorts of oddities and oversights, but I've fixed it.

The problem was the missing trailing '/' at the end of the namespace. NOT the namespace declared for the Android globals, but the namespace declared on the Web Service itself near the top of the service.asmx.cs file. (Directly above WebServiceBinding).

Once I added it to the end, everything was functioning like a champ.

Oddly enough, this obviously affects ONLY methods that take parameters as those methods without parameters were working perfectly. And only with KSoap2 as my web site that uses the exact same services was functioning flawlessly.

1
votes

That might be not the answer you'd like to hear, but, generally, if I were in your shoes, I'd consider switching away from SOAP (to REST-style web service, for example).

There are myriads of articles criticizing SOAP (and WSDL, and UDDI) floating around - you've probably seen some of them, such as 1, 2, 3 - and, indeed, they're a bit old, but still very true. You're experiencing now exactly what's SOAP being criticized much about - utter complexity and general incompatibility of various implementations - especially cross-platform.

0
votes

In You DOT NET WEB SERVICE see the function below:

[SoapRpcMethod]
[WebMethod]
public Complex GetComplex(string Name)
{
    Complex myObj = new Complex();
    if (Name == "" || Name == null ) Name = "empty param";
    myObj.name = "Return FRom My " + Name;
    myObj.value = 888;
    return myObj;
}

WHEN YOU USE [SoapRpcMethod] because of return Complex type. IN YOUR JAVA Programe:

SoapObject rpc4 = new SoapObject(serviceNamespace, "GetComplex");

rpc4.addProperty("Name", "Johnson TONG");

Below codes are also working too

PropertyInfo pi = new PropertyInfo();
pi.name= "Name";
pi.type = PropertyInfo.STRING_CLASS;

rpc4.addProperty(pi, "Johnson");

int MyCount = rpc4.getPropertyCount();
SoapSerializationEnvelope envelope4 = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope4.bodyOut = rpc4;
envelope4.dotNet = false; // <--

Don't ever use envelope4.dotNet = true this will always passing null value to the Server for reason that I don't know.

envelope4.setOutputSoapObject(rpc4);
envelope4.addMapping("http://tempuri.org/encodedTypes", "Complex", new Complex().getClass());
HttpTransport ht4 = new HttpTransport(serviceUrl);
ht4.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
ht4.debug = true;
0
votes

I have noticed a problem with boolean params. I noticed that your code doesn't have any currently, but this is just a heads up. I just changed the booleans to ints

0
votes

in my case, I lost much time trying to use SOAP, I had many errors, until you use REST.

This link leads to a tutorial for using REST

http://programmerguru.com/android-tutorial/android-restful-webservice-tutorial-how-to-call-restful-webservice-in-android-part-3/