Data Points

Accessing Data from a Mobile Application

John Papa

Code download available at:DataPoints2008_01.exe(179 KB)

Contents

Mobile Development
Getting Started
Automatic Binding
Binding the Fields
Mobile Binding Options
Fine-Tuning Your Mobile App
Final Thoughts

Data access is an important aspect of developing applications with the Microsoft® .NET Compact Framework for Windows Mobile® devices. By using the existing architecture to send and receive data between your mobile application and your application server, you can pass data with either DataSets, custom objects, or scalar values.

In this installment of DataPoints, I want to discuss best practices for data access strategies when developing mobile applications for Smartphones. I will demonstrate how to design a data-driven Smartphone application that can display and save data over the Internet. I will show you how to communicate with a server application that exposes methods to get data using a DataSet, custom objects, and a generic List<T> of entities.

Mobile Development

Essential Tools for Mobile Development

To develop mobile applications, you must first install the .NET Compact Framework (and its latest service pack). The latest update is the .NET Compact Framework 2.0 with SP2. Before diving in, you must make some decisions about the platform (Windows Mobile 5.0 or Windows Mobile 6) and the device (or devices) you are going to target for your application. These decisions will affect which SDKs you must install.

The Windows Mobile 5.0 SDK is available in different versions, depending on whether you are targeting a Smartphone, a Pocket PC, or a Pocket PC Phone. The Windows Mobile 6 SDK is also available in different versions for different target platforms, but the naming conventions have changed and are now a bit less intuitive. Figure 1 lists the various SDK versions and which devices they can target. It goes without saying that if you want to target each type of device, you should install each of the SDKs.

Figure 1 Windows Mobile SDKs

Target Device Required Windows Mobile 5.0 SDK Required Windows Mobile 6 SDK
Smartphone Windows Mobile 5.0 SDK for Smartphone Windows Mobile 6 Standard SDK
Pocket PC Windows Mobile 5.0 SDK for Pocket PC Windows Mobile 6 Professional SDK
Pocket PC Phone Windows Mobile 5.0 SDK for Pocket PC Windows Mobile 6 Professional SDK

For this discussion, I am using Windows Mobile 5 for the Smartphone. The version is not critical, though, as the data-access concepts presented remain the same regardless of version.

After installing the .NET Compact Framework 2.0 with SP2 and the appropriate Windows Mobile SDK, you must also install ActiveSync (for Windows® XP) or Windows Mobile Device Center (for Windows Vista®). These are needed for the mobile device emulator to communicate with your network or the Internet.

You should also download and install an emulator that closely resembles the device you are targeting. For this column, I have opted for a landscape 320x240 screen. If your target devices have different screen sizes, you should test your app for each using all of the appropriate emulators.

If you are using Windows Vista or the Windows Mobile 6 SDK, you need to install the Device Emulator 2.0. I know that this sounds like a lot of prerequisites to put in place, so I've included a list of links with this column in the download and on the MSDN Magazine Web site at msdn.microsoft.com/msdnmag/issues/08/01/datapoints.

Getting Started

I highly recommend testing on both the emulator and the device itself to avoid those situations when the application works fine on the emulator but not on the device. My approach is to use the emulator throughout the process of developing a mobile application, then deploy the application to a real mobile device at certain checkpoints.

Before debugging, make sure you run the Device Emulator from the Tools menu in Visual Studio®. Once you choose the emulator you want, right-click on it and select Connect. The emulator will then begin to boot the Smartphone. Once the Smartphone is running in the emulator, right-click the item in the Device Manager again and select Cradle. Cradling allows the emulator to communicate with the network. Finally, in Visual Studio, select an emulator from the dropdown list in the Device toolbar (see Figure 2).

Figure 2 Selecting a Target Emulator

Figure 2** Selecting a Target Emulator **

To get data, my sample application communicates with a Web service on an IIS Web server. The Web service works well for mobile applications, as it can pass both ADO.NET objects—such as the DataSet—and custom entities. First, I create a Web service project and add a WebService called CustomerWebService. I add three methods to the WebService and decorate each with the WebMethod attribute:

[WebMethod] public Customer GetCustomer(string customerID) { ... } [WebMethod] public DataSet GetCustomerDataSet(string customerID) { ... } [WebMethod] public List<Customer> FindCustomerList() { ... }

The GetCustomer method retrieves a single customer record in the form of a custom entity. The GetCustomerDataSet method also gets a single customer record, but this method returns the customer in a DataSet. The FindCustomerList method gets a list of customers, returning a List<Customer>, thus taking advantage of customer entities and generics. The full code for this Web service is included in the downloadable code.

Once the Web service is created, I add a Windows Mobile 5.0 Smartphone application to the solution. If you install both the Windows Mobile 5.0 and Windows Mobile 6 SDKs, you can choose the target application from this dialog. For this project, I am creating a Windows Mobile 5.0 Smartphone Device Application.

The Smartphone application will have a startup form that displays a list of customers in a dropdown list. The user can select one of the customers and then view the details of the customer on another page. The list of customers is retrieved from the Web service's FindCustomerList Web method, which brings back a List<Customer> to the form. The list can then be manually or automatically bound to the dropdown list. (I will demonstrate both techniques shortly.)

Automatic Binding

The CustomerPicker form is the first screen the user will see. I add a dropdown list to this form and name it ddlCustomer. I want to take advantage of automatic binding and bind my dropdown list to the List<Customer> that I will get back from my FindCustomerList Web method. I add a new data source to the project, selecting the type of entity to which I want to bind the dropdown list. Since I reference my Web service, the application knows what types of entity that my WebMethods return. This makes it easy to bind to the dropdown list with strongly typed entities.

I go to the Data Sources window and click on Add New Data Source—this pops up the wizard. I choose to add an object type, click next, and locate my Customer entity from the provided list (see Figure 3). If you don't see your entities in the list when adding a new data source, make sure you have first successfully compiled the Web service project and then go back and try again to add the data source. When an entity is exposed by the Web service, it will not show up in the list unless the DLL has first been compiled.

Figure 3 Creating a Customer Data Source

Figure 3** Creating a Customer Data Source **(Click the image for a larger view)

Once the data source has been added, I drag the new Customer Data Source (see Figure 4) from the Data Sources window to the dropdown list. This automatically creates a BindingSource control on the form named customerBindingSource, and this handles the two-way binding of the Customer entity to the controls.

Figure 4 Using a Customer Data Source

Figure 4** Using a Customer Data Source **

There are two more steps to set up the automatic binding before I can test my application in the emulator. The next step is to set the DisplayMember and the ValueMember properties of the dropdown list. I set the DisplayMember property to the CompanyName and the ValueMember property to the CustomerID. Since the data source is strongly typed, these values are in a dropdown list in the properties window for the dropdown list control.

The last step is to tell the BindingSource control where to get its data. This is as simple as creating an instance of the Web service proxy class, invoking the appropriate method, and setting its returning List<Customer> to the BindingSource control's DataSource property, like so:

private void CustomerPicker_Load(object sender, EventArgs e) { using (RemoteService.CustomerWebService svc = new RemoteService.CustomerWebService()) customerBindingSource.DataSource = svc.FindCustomerList(); }

At this point, you can run the application and test it to see if it displays the list of customers in the dropdown list. Make sure that you have set the target device in Visual Studio, that you are running ActiveSync® or Windows Mobile Device Center (as appropriate), and that the device you are emulating is cradled (use the Device Emulator Manager).

Binding the Fields

After creating and testing the CustomerPicker form, I then create another form called CustomerDetail. This will display the selected customer. I change the data source settings so that the details controls are created when I drag the Customer data source to the form, and then I customize which properties to display from the Data Source window. Afterwards, I drag the controls to the CustomerDetail form. Figure 5 shows the Data Source after I have customized it.

Figure 5 Customized Data Source

Figure 5** Customized Data Source **

Now I must get the selected Customer record from the Web service's GetCustomer Web method. I use the CustomerID that was selected from the previous form and call the GetCustomer Web method. The Customer entity that is returned is then set to the Data source of the customerBindingSource control on the CustomerDetail form. I now test the application again in the emulator, and I see the screen shown in Figure 6.

Figure 6 Application Running in the Emulator

Figure 6** Application Running in the Emulator **

Mobile Binding Options

It is very easy to implement automatic binding using the BindingSource control in a mobile device application. It works similarly to how the BindingSource control works in a Windows Forms application, with the notable exception being the lack of a BindingNavigator control. Since mobile apps don't have a BindingNavigator control, you have to write code for navigating from one record to the next if you want that functionality. I tend to avoid that type of feature since it is typically used when retrieving a large list of items. This can affect performance in a mobile application, as the mobile device usually has limited bandwidth. So the lack of a BindingNavigator is not a bad thing since it reminds you to be economical with bandwidth.

BindingSource takes the headache out of manually getting the values from the entity and stuffing them into the controls on the form. When saving a record, BindingSource also eliminates the hassle of retrieving the values from the form's controls and pulling them back into an entity. The downside of a BindingSource is that loading data can be slightly slower than when loading data manually.

I still recommend using the BindingSource control unless the performance difference is too great during your tests. I, however, have often found its performance to be adequate. The automatic binding you get when you use the BindingSource control is also very useful when you need to bind the same set of data to multiple controls.

Changing to manual binding is simple. All it requires is removing the BindingSource control, clearing the Data source settings of the controls on the form, and writing some code to manually load each value from the entity into the corresponding control, like this:

using (RemoteService.CustomerWebService svc = new RemoteService.CustomerWebService()) { RemoteService.Customer customer = svc.GetCustomer(_customerID); companyNameTextBox.Text = customer.CompanyName; customerIDLabel1.Text = customer.CustomerID; ... }

Note that when using a manual technique, you must also account for how to extract the data from the controls when the user wants to save the data. It's a simple procedure of grabbing the values from the controls and pulling them into an entity, but it is an extra step that you must handle when you want to allow users to save information. A common practice with manual binding is to store the Customer entity as a private field of the CustomerDetail form so you can readily access it when you need to pull the data out of the controls and back into the entity.

Fine-Tuning Your Mobile App

Since bandwidth may be limited and processors on mobile devices are slower than desktop computers, it is important that you only pass the minimum amount of data needed by the application. In my sample application, I retrieved a list of Customer entities, but only used two of the properties of each entity. This wasted a lot of bandwidth for the CustomerPicker screen since it had to go and get all of the data for all of the customers.

A more efficient approach would be to create a method that retrieves just the CustomerID and CompanyName for each customer. Considerations like these are important to remember when tuning your mobile application, as performance issues like these may not show up in a desktop application.

Final Thoughts

Before you dive into mobile development, it is important that you get yourself properly set up. You must make sure you have the right emulator manager version, the appropriate emulators, the correct SDKs, and the necessary version of ActiveSync or Windows Mobile Device Center. When I ran my application on Windows Vista, the emulator would not communicate with my Web service until I installed the Windows Mobile Device Center 6.1 and the Device Emulator Manager 2. These are important updates to the software that must be installed when running in Windows Vista, even when targeting Windows Mobile 5.0.

If you get an error when trying to get ActiveSync to see your emulator, make sure that ActiveSync is set to communicate through DMA. If you get an error when trying to access your Web service, make sure the Web service uses your server's name, as opposed to localhost. Localhost will work fine on your PC, but when the emulator tries to reconcile localhost, it will not know that you meant your computer's Web server. Another good tip is to make sure you connect and cradle your emulated device so it can communicate with the local PC.

If you need information about deploying your application to a real mobile device, check out my December 2006 installment of Data Points, "RSS Feeds on a Smartphone" (which is available at msdn.microsoft.com/msdnmag/issues/06/12/DataPoints).

Send your questions and comments for John to mmdata@microsoft.com.

John Papa is a Senior .NET Consultant with ASPSOFT (aspsoft.com) and a baseball fanatic who spends most of his summer nights rooting for the Yankees with his family and his faithful dog, Kadi. John, a C# MVP, has authored several books on ADO, XML, and SQL Server. He can often be found speaking at industry conferences, such as VSLive.