MonoAndroid: Using dotnet webservice (ASMX)
Using ASMX webservices in your mobile application.
Introduction
Here, Once again I am back with another article in my series of MonoAndroid, for previous article refers at bottom portion. In this article I am going to demonstrate using ASMX Web Service (Non-WCF) in Mobile App.
Web services are becoming integrated part of mobile and web applications. Mono Android support almost all type of Web Services like Restful, WCF and normal SOAP based web services. In this article I am going to create dotnet based web service and consuming same in my mobile application.
In this article I will create Software Developer Hierarchy app. In this we will create dotnet web service, where we provide web method which will send the list of software person with their designations and show them on our android mobile ListView.
Step By Step we move forward
- Create Android application by selecting New ->Solutions and
provide its name “
MonoWebService
”
Figure 1: Creating Android Project! -
Now by default, when you create project in the android, it contain a button. So application flow would be on click of button, we will invoke web service and fill the ListView with the retrieved data.
So Button text contains “Hello World” and when we check button properties, it will show its referring to string resource, Means button label is coming from string table.
Now to change text on the button, you have to modify strings.xml under Resources\values. Just look for name “hello” and change the name to “Retrieve Data from Web service”. See i marked line in bold.
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Retrieve Data from Web service</string> <string name="app_name">MonoWebService</string> </resources>
- Now add the ListView in the MainActivity file, after adding that, UI code looks
something like this :-
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/myButton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <ListView android:minWidth="25px" android:minHeight="25px" android:layout_width="fill_parent" android:layout_height="match_parent" android:id="@+id/Main_ListView" /> </LinearLayout>
-
Now time if for you to create web service in visual studio 2010. Now open the “Create New Project”, change .Net framework 3.5 to make ASP.NET Web Service Application project available for selection.
Now create the project by name “MonoAndroidWebService“
-
Now change the name of default
Service1
toMonoDataService
and delete anything else there. Now addGetWebServiceMonoDatas()
method which returns hardcoded list of WebServiceMonoDatapublic class MonoDataService : System.Web.Services.WebService { [WebMethod] public List<WebServiceMonoData> GetWebServiceMonoDatas() { var lstFragmentDemo = new List<WebServiceMonoData> { new WebServiceMonoData() { Name = "Alok Gupta", Desigination = "Snr Software Engineer" }, new WebServiceMonoData() { Name = "Jasdeep Singh", Desigination = "Snr Auditor (Information)" }, new WebServiceMonoData() { Name = "Ashish Srivastava", Desigination = "Software Test Engineer" }, new WebServiceMonoData() { Name = "Hariharan Ramchandran", Desigination = "Product Architect" } }; return lstFragmentDemo; } }
Now following is the code of WebServiceMonoData class
[Serializable] public class WebServiceMonoData { public string Name { get; set; } public string Desigination { get; set; } }
Since we are sending our class using services over http, we need to make our class Serializable. Build and compile webservice, so that it would be available for creating web reference.
-
Now In your mobile application, right click on the Project->Add-> Add Web Reference, see I marked that in following screenshot
Change web service URL to your local service address which is “http://localhost:61847/MonoDataService.asmx” in my case. Select framework .Net 2.0 web services and provide reference as “MonoDataService”
- Now add following code in MainActivity file, I will explain the further down
public class MainActivity : Activity { protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); // Set our view from the "main" layout resource SetContentView (Resource.Layout.Main); Button button = FindViewById<Button> (Resource.Id.myButton); button.Click += OnWebserviceRetrievedInformation; } void OnWebserviceRetrievedInformation (object sender, EventArgs e) { var objMonoAndroidService = new MonoDataService.MonoDataService (); objMonoAndroidService.BeginGetWebServiceMonoDatas (WebServiceCallBack, objMonoAndroidService); } void WebServiceCallBack (IAsyncResult ar) { var objMonoAndroidService = ar.AsyncState as MonoDataService.MonoDataService; var arrWebServiceMonoDatas = objMonoAndroidService.EndGetWebServiceMonoDatas (ar); var lstWebServiceMonoData = new List<MonoWebService.MonoDataService.WebServiceMonoData>(arrWebServiceMonoDatas); var mainListView = FindViewById<ListView>(Resource.Id.Main_ListView); mainListView.Adapter = new ListBaseAdapter (this, lstWebServiceMonoData); } }
Above we are doing following- On button click create the object of the MonoDataService.MonoDataService and invoke GetWebServiceMonoDatas method asynchronously.
- In the callback function, creating the List of WebServiceMonoData from retrieved array and passing it to our custom adapter to create ListView. Here is the code of our custom BaseAadapter derived class.
public class ListBaseAdapter: BaseAdapter<WebServiceMonoData> { List<MonoWebService.MonoDataService.WebServiceMonoData> _lstWebServiceMonoData; Activity _mainActivity; public ListBaseAdapter (Activity mainActivity, List<MonoWebService.MonoDataService.WebServiceMonoData> lstWebServiceMonoData) { _lstWebServiceMonoData = lstWebServiceMonoData; _mainActivity = mainActivity; } #region implemented abstract members of BaseAdapter public override long GetItemId (int position) { return position; } public override View GetView (int position, View convertView, ViewGroup parent) { var item = this [position]; if (convertView == null) convertView = _mainActivity.LayoutInflater.Inflate (Android.Resource.Layout.SimpleListItem2, parent, false); convertView.FindViewById<TextView> (Android.Resource.Id.Text1).Text = item.Name; convertView.FindViewById<TextView> (Android.Resource.Id.Text2).Text = item.Desigination; return convertView; } public override int Count { get { return _lstWebServiceMonoData== null? -1: _lstWebServiceMonoData.Count; } } #endregion #region implemented abstract members of BaseAdapter public override WebServiceMonoData this [int index] { get { return _lstWebServiceMonoData== null? null: _lstWebServiceMonoData[index]; } } #endregion }
You can learn more about creating custom Base Adapter here
-
Now build and run your mobile application, you will see this ugly exception popping up :-
Problem here is that your mobile app trying to find the Web Service in local mobile, where it’s not present as it present on the development machine. Now to access web service from your emulator you need to use magic IP address 10.0.2.2, instead of LocalHost. Now while creating web service object pass the URL like this :-
void OnWebserviceRetrievedInformation (object sender, EventArgs e) { var objMonoAndroidService = new MonoDataService.MonoDataService ("http://10.0.2.2:61847/MonoDataService.asmx"); objMonoAndroidService.BeginGetWebServiceMonoDatas (WebServiceCallBack, objMonoAndroidService); }
-
Try again to build and run mobile app, you again encountered exception, this time it’s due to updating UI control from worker thread.
Now to solve this problem, move these two line under
RunOnUiThread
under WebServiceCallBack method like this :-RunOnUiThread (() => { var mainListView = FindViewById<ListView> (Resource.Id.Main_ListView); mainListView.Adapter = new ListBaseAdapter (this, lstWebServiceMonoData); });
- Now Build and Run the application,
On 4 Inch Screen On Button Click
Magic IP table
This section text is taken from here, word by word.
The virtual router for each instance manages the 10.0.2/24 network address space — all addresses managed by the router are in the form of 10.0.2.<xx>, where <xx> is a number. Addresses within this space are pre-allocated by the emulator/router as follows:
Network Address | Description |
10.0.2.1 | Router/gateway address |
10.0.2.2 | Special alias to your host loopback interface (i.e., 127.0.0.1 on your development machine) |
10.0.2.3 | First DNS server |
10.0.2.4 / 10.0.2.5 / 10.0.2.6 | Optional second, third and fourth DNS server (if any) |
10.0.2.15 | The emulated device's own network/ethernet interface |
127.0.0.1 | The emulated device's own loopback interface |
Points of Interest
I have used MonoAndroid for C# and Xamarin Studio to build this tutorial. Watch out, if I continue learning it, you can expect more articles coming soon.
Though Xamarin Studio is proprietary software, however they provide free starter version to built, test and publish android application. I am using same for my learning.
Articles in this series!
- MonoAndroid: Writing custom generic BaseAdapter in C#
- MonoAndroid: Using GridView in your mobile application
- MonoAndroid: Using TabHost in your mobile applications
- MonoAndroid: Using Fragments in mobile app
- MonoAndroid: Using Started Service
- MonoAndroid: Calling secondary activity
- MonoAndroid: Writing ExpandableListView amd BaseExpandableListAdapter in C#
- MonoAndroid: Using AlertDialog
Tips/Tricks in this Series
History
- 22-Aug-2013: First Version
- 06-Sept-2013: Updated Tips and Tricks Section
- 10-Oct-2013: Updated Tips and Tricks Section
- 04-Nov-2013: Update Article series
- 22-Nov-2013: Updated other article section