Monthly Archives: June 2010

Access .Net webservices which return complex types

I thought it was pretty simple for a beginner like me to parse the dataset returned from .Net webservices. I tried all the options, tried to map like
envelope.addMapping(“Namespace”, “class or tag”, classname);
but this one works fine with the complex types not with the datasets. Or maybe I might have missed something, I was not able to parse data.

For simple types we can use this

private SoapObject table = null;       // Its the table of a DataSet
private SoapObject client = null;       // Its the client pettition to the web service
private SoapObject tableRow = null;      // Gets the information of a row from the table DataSet
private SoapObject responseBody = null;     // Its the whole response of the WebService
private HttpTransport transport = null;     // Its whta is used to make the call to the WebService
private SoapSerializationEnvelope sse = null;
sse = new SoapSerializationEnvelope(SoapEnvelope.VER11); // SOAP version is indicated here. Version 11 works nice
sse.addMapping(<webService NameSpace>, <name of the Class using it>, this.getClass());
sse.dotNet = true; // We stablish we sill be working with .NET webservices
transport = new HttpTransport(<url of the webservices>);
transport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); transporte.debug = debug; // Set it to either use transport.requestdump or reponsedump to see the xml of the webservice request or response
// Here we set who are we gonna call, give the method arguments and do the call
client = new SoapObject(<webServiceNameSpace>, <webService Method Name we want to reuqest>);
// You can add as many properties as many as you need. I'd say that you set your webservices method to recieve only strings and do the convertions on you webservice. Its quite hard work with primitive values
client.addProperty(<agument name as String>, <argument Value>);
sse.setOutputSoapObject(client);
sse.bodyOut = client;
transporte.call(<webService direct url>, sse);
// We'll get the whole XML reponse with all the information
responseBody = (SoapObject) sse.getResponse();
// Now, the reponse works as a Vector. On position 0 we have the information of the Reponse while in position 1 we get the info we requested. So we get rid of the information reponse and lets grab the info we requested
responseBody = (SoapObject) responseBody.getProperty(1);
// And now, we have the n tables the WebService returned to us with the information, but still we can't access the info, so we'll get one of the tables separated. We'll use a very different variable for not to lose the whole info the webservice sended us. Once again, the tables are contained on a Vector. Lets grab the first one
table = (SoapObject) responseBody.getProperty(0);
// Now we have the table, but still can't use the info, soooo, lets grab a row individually
tableRow = (SoapObject) table.getProperty(0);

tableRow.getProperty(<columnName>).toString()

sse.getResponse()

It worked pretty fine when we have few records.

I parsed the responsedump xml to parse the response data into objects using SAXParser. I felt this one to be easy way.

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
XMLReader reader = parser.getXMLReader();
//Use the handler to parse the XML
ExampleHandler handler = new ExampleHandler();
reader.setContentHandler(handler);
reader.parse(new InputSource(new ByteArrayInputStream(transport.responsedump.getbytes())));
Object object = handler.parsedata();

The response can be captured from handler. You need to create a handler with the parsedata.

Hope this helps..

Consuming webservice from Android

I was trying to consume .Net webservices from Android application using ksoap2-for-android sdk, I was getting proper response when there are no parameters to pass. When I’m trying to pass parameters, I was not succeeded. I seached lots of forums, there are so many suggestions, after implementing them I was able to send parameters and get the response correctly.

This was my code:

private static final String SOAP_ACTION = "http://tempuri.org/CelsiusToFahrenheit";
private static final String METHOD_NAME = "CelsiusToFahrenheit";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String strURL = "http://w3schools.com/webservices/tempconvert.asmx";
TextView tv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv =(TextView)findViewById(R.id.TextView01);
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("Celsius","23.5");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet=true;
envelope.encodingStyle=SoapSerializationEnvelope.ENC;
envelope.setOutputSoapObject(request);
AndroidHttpTransport transport ;
try
{
transport = new AndroidHttpTransport(strURL);
transport.debug=true;
transport.setXmlVersionTag(/"<?xml version=/"1.0/" encoding=/"utf-8/"?/>");
transport.call(SOAP_ACTION, envelope);
SoapPrimitive resultString = (SoapPrimitive)envelope.getResponse();
tv.setText("Status:" + resultString.toString());
catch(Exception e){
e.printStackTrace();
}
}

To resolve the issue regarding Outbound parameters passed as null, the following suggestions were been provided:

1. If you are using IE set to Access data across domains to enabled
2. change addProperty(“Temperature”,”23.5″); to addProperty(“arg0″,”23.5”); even without implementing this suggestion also I was able to connect
3. Set the encoding style for the envelope.
4. Set the boolean dotnet if you are connecting .Net web service
5. There is also a workaround to use ksoap and java.net tools combined to connect to webservice with the entire soap body specified.
6. Set the Content-Type
7. And if you are connecting a webservice on your localmachine, then provide the ipaddress rather than localhost/webservicename like 198.10.129.2/webservicename
8. Sometimes UAC blocks the connection, try running eclipse in administrator mode.

These are the suggestions kept together any of them may work for you..

Hope this saves someone’s day

Page is accessing information that is not under its control while accessing a webservice

When I created a html page which consumes a webservice which is on some other domain, I used to get the prompt box on ie7 which says “Page is accessing information that is not under its control. This poses a security risk. Do you want to continue” with yes/no buttons. When I click yes, it works fine but when I click no it said Permission denied. I wanted to suppress this error.
It’s far from a perfect system, but it’s simple. Since there is no way to specify which pages trust other pages to access their data, Internet Explorer simply says that if two pages are not in the same domain, they cannot communicate. More precisely, Zone Manager (found on the security tab in Internet Settings) does allow the user to say that a page may access another page, but as you point out, most people leave it set on prompt.
You can suppress it getting into Internet Options -> Security Tab select internet and click custom actions button, in the pop up enable “Access data sources across domains” which is in the miscellaneous section.
You can suggest users add the page to the trusted site zone, or merely say Yes to the dialog box. Cross-domain security issues can be quite serious. Whenever you access data sources that are in a different context than your script, there are potential problems. A solution here would be to create a safe ActiveX® control that will perform the tasks you need and lock it down to the intranet site or creating a webservice in your local domain and accessing the webservice from different domain from your webservice. You can use your webservice in your application.

Google newshow wizard

I was trying to place some news wizard on my blog, either fetching google news from webservice or api, but unfortunately Google is not providing any api for google news as of now. You can either use Rss feed and AJAX Search API. I tried implementing this AJAX search API, its quite easy, go to http://code.google.com/apis/ajaxsearch/documentation/newsshow/wizard.html and
update the wizard as per your requirement, what news you want to display on your webpage kind… Once you selected the options on the wizard.html, it will create a html code to paste it in your page. And there you go… news on your page.. you can set the iframe size if you want to display news using large space, horizontal or vertically.