views:

139

answers:

3

Hi everyone,

I have the following code which invokes a .net webservice. The code connects to the service fine, but the paramter(deviceid) does not appear to get passed. The method simply returns the passed deviceid which is always null.

This is telling me the deviceid parameter is not being passed. I thought I saw someone recommend a packet sniffer to view the outgoing xml, but can't seem to remember what it was. Can someone suggest one that i can use in conjunction with eclipse and windows.

activity code

    String deviceid = tManager.getDeviceId();

    SoapObject request = new SoapObject(NAMESPACE,METHOD_NAME);

    PropertyInfo pi = new PropertyInfo();

    pi.setName("deviceid");
    pi.type = PropertyInfo.STRING_CLASS;
    pi.setValue(deviceid.toString());
    request.addProperty(pi);

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

    HttpTransportSE ht = new HttpTransportSE(URL);


    try{
        ht.call(SOAP_ACTION, soapEnvelope);
        SoapPrimitive result = (SoapPrimitive ) soapEnvelope.getResponse(); 


        Toast.makeText(ctx, "result = " + result.toString(), Toast.LENGTH_SHORT).show();

    }catch(Exception e){
        e.printStackTrace();
        Toast.makeText(ctx, "error: " + e.getMessage(), Toast.LENGTH_SHORT).show();

    }

webservice code

        <WebMethod()> _
    Public Function CheckTrial(ByVal deviceid As String) As String

        Return deviceid
    End Function

I,ve tried everything and cannot figure out how to resolve this. Does anyone else have any suggestions to try?

xml sent as spy'ed from wire shark:

POST /android_service_test.asmx HTTP/1.1 
Host: ikonicsoft.com 
user-agent: kSOAP/2.0 
soapaction: http://ikonicsoft.com/CheckTrial 
content-type: text/xml 
connection: close 
content-length: 421  
<?xml version="1.0" encoding="UTF-8"?>
<v:Envelope xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:d="http://www.w3.org/2001/XMLSchema" 
xmlns:c="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:v="http://schemas.xmlsoap.org/soap/envelope/"&gt;
<v:Header />
<v:Body>
    <CheckTrial xmlns="http://ikonicsoft.com" id="o0" c:root="1">
        <deviceid i:type="d:string">000000000000000</deviceid>
    </CheckTrial>
</v:Body>
</v:Envelope>

HTTP/1.1 200 OK 
Connection: close 
Date: Mon, 21 Jun 2010 16:35:10 GMT 
Server: Microsoft-IIS/6.0 
X-Powered-By: PleskWin 
X-Powered-By: ASP.NET 
X-AspNet-Version: 2.0.50727 
Set-Cookie: .ASPXANONYMOUS=fnyqjfFHywEkAAAAZGVjYjZmNTEtNWNiYi00YTIwLWEzYzktNzUxZDNjMDA0OGY00; 
expires=Mon, 30-Aug-2010 03:15:09 GMT; path=/; HttpOnly 
Cache-Control: private, max-age=0 
Content-Type: text/xml; charset=utf-8 
Content-Length: 299  

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
<soap:Body>
    <CheckTrialResponse xmlns="http://ikonicsoft.com/" />
</soap:Body>
</soap:Envelope>

Thanks

Patrick

+1  A: 

If I'm not mistaken, ht.call(...) returns a SoapSerializationEnvelope. I believe you need to pull your response out of that envelope and not out of the one you passed in

SoapSerializationEnvelope responseEnvelope = ht.call(SOAP_ACTION, soapEnvelope);
SoapPrimitive result = (SoapPrimitive ) responseEnvelope.getResponse(); 

If that doesnt work: Are you using ksoap2 for android (there is a Java version and an Android version)? does your webservice require you to log in? while trying to perform a similar task i found that ksoap was not storing session cookies, particularly the session id. we had to extend ServiceConnection and HttpTransportSE to save the cookie as a String in order to maintain a login

As far as packet sniffers go, check out wire shark.

mtmurdock
My understanding is that the response populates the soapEnvelope object passed to the ht.call(). All the example code I've seen shows this. I did however try your suggestion, and it would not compile. the error is Type mismatch: cannot convert from void to SoapSerializationEnvelopeI am using ksoap2 for android. The service does not require any login. I'm trying to keep it simple until I can figure this out.I'll have to check out wire shark. I want to confirm the xml to make sure its passing the parameter.
I dont remember off the top of my head what the return type of ht.call() is, but i remember that i stored it in my variable "envelope". your properties could be part of your problem. I didnt use the PropertyInfo class at all, rather i called addProperty(string,string).if you come up with any more info from wire shark post it and ill see if i can help
mtmurdock
Ok, I added output from wire shark at the bottom of the Question. It appears the deviceid is being sent. Why then would it not be picked up by the service method. Could it possibly be due to the differences in the xml namespaces. If you view the service description (http://ikonicsoft.com/android_service_test.asmx) it uses <soap:Body> instead of what is sent from ksoap2 <v:Body>?? I'm still at a loss. Is the webservice nat able top parse the incoming xml correctly??
does your web service have any way of detecting if you are hitting it at all? You should check this out server side and see if you are even getting there at all. i ask because there is a possibility that you aren't setting your URLs correctly or some similar problem. your URL should be "http://ikonicsoft.com/android_service_test.asmx" and i believe your namespace will be "http://ikonicsoft.com/"
mtmurdock
Sort of yes...I had originally coded the method to use the passed deviceid to query a db table. The method used a command object with a paramter to execute a stored procedure. The parameter name was @DEVICEID (_cmd.Parameters.AddWithValue("@DEVICEID", deviceid)). When i ran it the soap server returned a soap fault. the error was a db error stating the parameter @DEVICEID was expected but was null. This lead me to believe the deviceid was not being passed to the method in the xml payload; but i was wrong. I am 100% sure the url, and namespace are correct(as you have above).
A: 

Try setting the namespace of the PropertyInfo object.

    pi.setNamespace(NAMESPACE);
Soumya Simanta
Thanks for the suggestion, but no go. I first tried thispi.setNamespace("soap"); which produced this:<n0:deviceid i:type="d:string" xmlns:n0="soap">then i triedpi.setNamespace(NAMESPACE); (http://ikonicsoft.com) and produced:<n0:deviceid i:type="d:string" xmlns:n0="http://ikonicsoft.com"> Is there any way to change programatically what the envelope uses <soap:> instead of <v:>thx
Namespaces are unique strings.In your example above <v:> is not a problem as long as v references to the right namespace string. Here v is just an alias. The XML parser will take care of resolving v to the right namespace string.In order for your web service (on the server) to understand the namespace references, the "all" namespace references in the SOAP request (from Android) should match the namespaces as defined in your WSDL. Are you able to invoke the service from a non-Android client?
Soumya Simanta
I've not tested against another client other then an http post test on my localhost. when you say the 'all' namespace, do you mean http://tempuri.org namespace, or in my case i have changed it to http://ikonicsoft.com
A: 

Try removing the colon (:) from your namespace in the webservice... ie just make it ikonicsoft.com instead of http://ikonicsoft.com - and update your soap reference calls as well to use the new namespace. It's crazy, but this solved my problem (on Blackberry, but the same principles apply I think).

Edit - this isn't ideal if you are trying to consume a webservice that you don't own, but it's at least a solution for consuming your own webservices. I am absolutely baffled as to why the colon in there is messing things up, but I noticed that doing an HTML post directly to the web server (by telnetting in to port 80 on the webserver), I get the same error.

Ryan
Hey Thanks Ryan. I will definatly give it a try.
Another thing to double check is that you have the trailing slash in your namespace... Ie: if it's defined as `http://ikonicsoft.com/` in your webservice, make sure that you have `http://ikonicsoft.com/` in your java code as well - as opposed to `http://ikonicsoft.com` - I made this mistake too, and it worked for calls without parameters, but NOT for calls with parameters.
Ryan