Consuming an ASP.NET Web Service (ASMX)

Encapsulating an Asynchronous Programming Model (APM) model proxy using Tasks

PDF for offline use
Sample Code:
Related APIs:

Let us know how you feel about this


0/250

last updated: 2016-09

ASMX provides the ability to build web services that send messages using the Simple Object Access Protocol (SOAP). SOAP is a platform-independent and language-independent protocol for building and accessing web services. Consumers of an ASMX service do not need to know anything about the platform, object model, or programming language used to implement the service. They only need to understand how to send and receive SOAP messages. This article demonstrates how to consume an ASMX SOAP service from a Xamarin.Forms application.

A SOAP message is an XML document containing the following elements:

  • A root element named Envelope that identifies the XML document as a SOAP message.
  • An optional Header element that contains application-specific information such as authentication data. If the Header element is present it must be the first child element of the Envelope element.
  • A required Body element that contains the SOAP message intended for the recipient.
  • An optional Fault element that's used to indicate error messages. If the Fault element is present, it must be a child element of the Body element.

SOAP can operate over many transport protocols, including HTTP, SMTP, TCP, and UDP. However, an ASMX service can only operate over HTTP. The Xamarin platform supports standard SOAP 1.1 implementations over HTTP, and this includes support for many of the standard ASMX service configurations.

Instructions on setting up the ASMX service can be found in the readme file that accompanies the sample application. However, when the sample application is run, it will connect to a Xamarin-hosted ASMX service that provides read-only access to data, as shown in the following screenshot:

In iOS 9 and greater, App Transport Security (ATS) enforces secure connections between internet resources (such as the app's back-end server) and the app, thereby preventing accidental disclosure of sensitive information. Since ATS is enabled by default in apps built for iOS 9, all connections will be subject to ATS security requirements. If connections do not meet these requirements, they will fail with an exception.

ATS can be opted out of if it is not possible to use the HTTPS protocol and secure communication for internet resources. This can be achieved by updating the app's Info.plist file. For more information see App Transport Security.

Consuming the Web Service

The ASMX service provides the following operations:

Operation Description Parameters
GetTodoItems Get a list of to-do items
CreateTodoItem Create a new to-do item An XML serialized TodoItem
EditTodoItem Update a to-do item An XML serialized TodoItem
DeleteTodoItem Delete a to-do item An XML serialized TodoItem

For more information about the data model used in the application, see Modeling the data.

The sample application consumes the Xamarin-hosted ASMX service that provides read-only access to the web service. Therefore, the operations that create, update, and delete data will not alter the data consumed in the application. However, a hostable version of the ASMX service is available in the TodoASMXService folder in the accompanying sample application. This hostable version of the ASMX service permits full create, update, read, and delete access to the data.

A proxy must be generated in order to consume the ASMX service, which allows the application to connect to the service. The proxy is constructed by consuming service metadata that defines the methods and associated service configuration. This metadata is exposed in the form of a Web Services Description Language (WSDL) document that is generated by the web service. The proxy is built by using Xamarin Studio or Visual Studio to add a web reference for the web service to the platform-specific projects.

The generated proxy classes provide methods for consuming the web service that use the Asynchronous Programming Model (APM) design pattern. In this pattern an asynchronous operation is implemented as two methods named BeginOperationName and EndOperationName, which begin and end the asynchronous operation.

The BeginOperationName method begins the asynchronous operation and returns an object that implements the IAsyncResult interface. After calling BeginOperationName, an application can continue executing instructions on the calling thread, while the asynchronous operation takes place on a thread pool thread.

For each call to BeginOperationName, the application should also call EndOperationName to get the results of the operation. The return value of EndOperationName is the same type returned by the synchronous web service method. For example, the EndGetTodoItems method returns a collection of TodoItem instances. The EndOperationName method also includes an IAsyncResult parameter that should be set to the instance returned by the corresponding call to the BeginOperationName method.

The Task Parallel Library (TPL) can simplify the process of consuming an APM begin/end method pair by encapsulating the asynchronous operations in the same Task object. This encapsulation is provided by multiple overloads of the TaskFactory.FromAsync method.

For more information about APM see Asynchronous Programming Model and TPL and Traditional .NET Framework Asynchronous Programming on MSDN.

Creating the TodoService Object

The generated proxy class provides the TodoService class, which is used to communicate with the ASMX service over HTTP. It provides functionality for invoking web service methods as asynchronous operations from a URI identified service instance. For more information about asynchronous operations, see Async Support Overview.

The TodoService instance is declared at the class-level so that the object lives for as long as the application needs to consume the ASMX service, as shown in the following code example:

public class SoapService : ISoapService
{
  ASMXService.TodoService asmxService;
  ...

  public SoapService ()
  {
    asmxService = new ASMXService.TodoService (Constants.SoapUrl);
  }
  ...
}

The TodoService constructor takes an optional string parameter that specifies the URL of the ASMX service instance. This enables the application to connect to different instances of the ASMX service, provided that there are multiple published instances.

Creating Data Transfer Objects

The sample application uses the TodoItem class to model data. In order to store a TodoItem item in the web service it must first be converted to the proxy generated TodoItem type. This is accomplished by the ToASMXServiceTodoItem method, as shown in the following code example:

ASMXService.TodoItem ToASMXServiceTodoItem (TodoItem item)
{
  return new ASMXService.TodoItem {
    ID = item.ID,
    Name = item.Name,
    Notes = item.Notes,
    Done = item.Done
  };
}

This method simply creates a new ASMService.TodoItem instance, and sets each property to the identical property from the TodoItem instance.

Similarly, when data is retrieved from the web service, it must be converted from the proxy generated TodoItem type to a TodoItem instance. This is accomplished with the FromASMXServiceTodoItem method, as shown in the following code example:

static TodoItem FromASMXServiceTodoItem (ASMXService.TodoItem item)
{
  return new TodoItem {
    ID = item.ID,
    Name = item.Name,
    Notes = item.Notes,
    Done = item.Done
  };
}

This method simply retrieves the data from the proxy generated TodoItem type and sets it in the newly created TodoItem instance.

Retrieving Data

The TodoService.BeginGetTodoItems and TodoService.EndGetTodoItems methods are used to call the GetTodoItems operation provided by the web service. These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

public async Task<List<TodoItem>> RefreshDataAsync ()
{
  ...
  var todoItems = await Task.Factory.FromAsync<ASMXService.TodoItem[]> (
    todoService.BeginGetTodoItems,
    todoService.EndGetTodoItems,
    null,
    TaskCreationOptions.None);

  foreach (var item in todoItems) {
    Items.Add (FromASMXServiceTodoItem (item));
  }
  ...
}

The Task.Factory.FromAsync method creates a Task that executes the TodoService.EndGetTodoItems method once the TodoService.BeginGetTodoItems method completes, with the null parameter indicating that no data is being passed into the BeginGetTodoItems delegate. Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

The TodoService.EndGetTodoItems method returns an array of ASMXService.TodoItem instances, which is then converted to a List of TodoItem instances for display.

Creating Data

The TodoService.BeginCreateTodoItem and TodoService.EndCreateTodoItem methods are used to call the CreateTodoItem operation provided by the web service. These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  ...
  var todoItem = ToASMXServiceTodoItem (item);
  ...
  await Task.Factory.FromAsync (
    todoService.BeginCreateTodoItem,
    todoService.EndCreateTodoItem,
    todoItem,
    TaskCreationOptions.None);
  ...
}

The Task.Factory.FromAsync method creates a Task that executes the TodoService.EndCreateTodoItem method once the TodoService.BeginCreateTodoItem method completes, with the todoItem parameter being the data that's passed into the BeginCreateTodoItem delegate in order to specify the TodoItem to be created by the web service. Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

The web service throws a SoapException if it fails to create the TodoItem, which is handled by the application.

Updating Data

The TodoService.BeginEditTodoItem and TodoService.EndEditTodoItem methods are used to call the EditTodoItem operation provided by the web service. These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
  ...
  var todoItem = ToASMXServiceTodoItem (item);
  ...
  await Task.Factory.FromAsync (
    todoService.BeginEditTodoItem,
    todoService.EndEditTodoItem,
    todoItem,
    TaskCreationOptions.None);
  ...
}

The Task.Factory.FromAsync method creates a Task that executes the TodoService.EndEditTodoItem method once the TodoService.BeginCreateTodoItem method completes, with the todoItem parameter being the data that's passed into the BeginEditTodoItem delegate in order to specify the TodoItem to be updated by the web service. Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

The web service throws a SoapException if it fails to locate or update the TodoItem, which is handled by the application.

Deleting Data

The TodoService.BeginDeleteTodoItem and TodoService.EndDeleteTodoItem methods are used to call the DeleteTodoItem operation provided by the web service. These asynchronous methods are encapsulated in a Task object, as shown in the following code example:

public async Task DeleteTodoItemAsync (string id)
{
  ...
  await Task.Factory.FromAsync (
    todoService.BeginDeleteTodoItem,
    todoService.EndDeleteTodoItem,
    id,
    TaskCreationOptions.None);
  ...
}

The Task.Factory.FromAsync method creates a Task that executes the TodoService.EndDeleteTodoItem method once the TodoService.BeginDeleteTodoItem method completes, with the id parameter being the data that's passed into the BeginDeleteTodoItem delegate in order to specify the TodoItem to be deleted by the web service. Finally, the value of the TaskCreationOptions enumeration specifies that the default behavior for the creation and execution of tasks should be used.

The web service throws a SoapException if it fails to locate or delete the TodoItem, which is handled by the application.

Summary

This article demonstrated how to consume an ASMX web service from a Xamarin.Forms application. ASMX provides the ability to build web services that send messages over HTTP using SOAP. Consumers of an ASMX service do not need to know anything about the platform, object model, or programming language used to implement the service. They only need to understand how to send and receive SOAP messages.

Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.