Christian Amado

Christian Amado

Ingeniero de software, desarrollador
Diseñado adaptado de Todd Motto

Consumo de servicio ASMX con Xamarin
Jun 30, 2017
lectura de 2 minutos
Editar entrada

Uno de los servicios más conocidos y utilizados en el mundo .NET es el servicio ASMX (utilizando el protocolo SOAP), si bien es cierto esta forma de crear servicios ha quedado obsoleta (más bien, reemplazada por otras nuevas) se sigue utilizando en nuestros días.

Resulta sencilla su creación y consumo, pero tiene algunos problemas de autenticación propias del protocolo SOAP. En esta entrada mostraré cómo consumir un servicio web SOAP desde una aplicación Xamarin.Android.

Para comenzar necesitamos un servicio web SOAP publicado (vía internet o de manera local). Para este ejemplo, utilizaremos un servicio web que se encuentra disponible en la Web (al momento de escribir esta entrada el servicio se encuentra funcionando). La dirección es: http://www.dneonline.com/calculator.asmx

Como verás es una calculadora, por lo cual, necesitaremos 2 número para realizar el cálculo y mostrar el resultado en un Toast.

El diseño de la aplicación lo presentaremos de esta manera, en el archivo Main.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:text="Primer número"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView1" />
    <EditText
        android:inputType="number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/num1" />
    <TextView
        android:text="Segundo número"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView2" />
    <EditText
        android:inputType="number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/num2" />
    <Button
        android:text="Sumar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnSumar" />
</LinearLayout>

Llamada Sincrónica

Aquí el servicio se consume de manera directa y se espera por el resultado. La clase MainActivity.cs quedaría de la siguiente manera:

using Android.App;
using Android.Widget;
using Android.OS;

namespace PruebaServicioWeb
{
    [Activity(Label = "PruebaServicioWeb", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        EditText num1;
        EditText num2;
        Button btnSumar;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView (Resource.Layout.Main);

            num1 = FindViewById<EditText>(Resource.Id.num1);
            num2 = FindViewById<EditText>(Resource.Id.num2);
            btnSumar = FindViewById<Button>(Resource.Id.btnSumar);

            btnSumar.Click += BtnSumar_Click;
        }

        private async void BtnSumar_Click(object sender, System.EventArgs e)
        {
            //Llamar al servicio web
            var proxy = new ServicioWeb.Calculator();
            int n1, n2, resultado;
            n1 = int.Parse(num1.Text);
            n2 = int.Parse(num2.Text);
                
            //Realizamos la llamada al método del servicio web
            resultado = proxy.Add(n1, n2);
            Toast.MakeText(this.BaseContext, resultado.ToString(),
                        ToastLength.Long).Show();
        }
    }
}

Llamada Asincrónica

Aquí el servicio se consume de manera directa y el resultado se retorna cuando esté disponible. La clase MainActivity.cs quedaría de la siguiente manera:

using Android.App;
using Android.Widget;
using Android.OS;

namespace PruebaServicioWeb
{
    [Activity(Label = "PruebaServicioWeb", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity
    {
        EditText num1;
        EditText num2;
        Button btnSumar;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            // Set our view from the "main" layout resource
            SetContentView (Resource.Layout.Main);

            num1 = FindViewById<EditText>(Resource.Id.num1);
            num2 = FindViewById<EditText>(Resource.Id.num2);
            btnSumar = FindViewById<Button>(Resource.Id.btnSumar);

            btnSumar.Click += BtnSumar_Click;
        }

        private async void BtnSumar_Click(object sender, System.EventArgs e)
        {
            //Llamar al servicio web
            var proxy = new ServicioWeb.Calculator();
            int n1, n2;
            n1 = int.Parse(num1.Text);
            n2 = int.Parse(num2.Text);
                
            //Crear llamada al método asincrónico para sumar.
            proxy.AddAsync(n1, n2);
            
            // Evento que espera por el resultado
            proxy.AddCompleted += Proxy_AddCompleted;
        }
        
        private void Proxy_AddCompleted(object sender, 
                ServicioWeb.AddCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                int resultado = e.Result;
                Toast.MakeText(this.BaseContext, resultado.ToString(),
                        ToastLength.Long).Show();
            }
        }
    }
}

De esta manera, consumimos de dos maneras distintas un servicio web SOAP para utilizarlo en nuestra aplicación Xamarin.

Jun 29, 2017

AX 2012: Asignar campo con valores predeterminados

El título es entendible para cumplir con el objetivo. Ahora bien, no es tan simple...

Jul 12, 2017

Xamarin: Cargar ListView desde una lista genérica

Cuando trabajamos con servicios Web, generalmente éste retorna listas con datos relacionados al tipo de...