Introducción

Incorporar un mecanismo de búsqueda adecuado en las aplicaciones es un escenario muy común hoy en día para construir soluciones con alta funcionalidad, usando diversos servicios especializados que estén al alcance de nuestra mano.  Live Search es un buen ejemplo de este tipo de servicios, el cual podemos utilizar efectuar búsquedas en sitios, imágenes, foros, etc.

En este artículo veremos cómo utilizar el servicio de búsqueda de Microsoft Live Search e incorporarlo en nuestras aplicaciones Silverlight.

API de Live Search

El API de Live Search está disponible hoy en día para implementar características de búsqueda en nuestras aplicaciones de cualquier tipo:  Windows, Web, Móvil, o RIA; como es el caso de este ejemplo ya que usaremos Silverlight.

Para poder usar esta API es necesario crear una cuenta, la cual te dará una llave única relacionada a tu cuenta de MSN.  Esta llave es requerida para crear la petición al servicio y obtener los resultados encontrados.

El API de Live Search soporta 3 tipos diferentes de protocolos:

  • JSON
  • XML
  • SOAP

La decisión de utilizar uno u otro depende directamente del tipo de aplicación en donde usarás esta API.  En nuestro caso utilizaremos SOAP aunque XML o JSON son también opciones bastante viables.

La dirección para obtener una llave es para Live Search es: http://search.live.com/developers/default.aspx

Creando la solución

Crearemos una nueva aplicación Silverlight utilizando la plantilla de Visual Studio .NET 2008 llamada SLSearch.  Esta aplicación será de tipo Application.


Creando el XAML

La aplicación necesita básicamente los siguientes controles:

  • Un control para que el usuario escriba la búsqueda que desee realizar
  • Un control para iniciar esa búsqueda
  • Un control para desplegar los resultados apropiadamente

El siguiente XAML crear un TextBox, Button y ListBox acomodados en un contenedor de tipo Grid.  El resultado de la búsqueda la desplegaremos como una serie de hipervínculos.

<UserControl x:Class="SLSearch.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal">
            <!--Caja de texto para escribir el texto de búsqueda-->
            <TextBox x:Name="txtConsulta" Height="26" Width="250" HorizontalAlignment="Left" Margin="2" />
            <!--Botón para consultar-->
            <Button x:Name="btnConsulta" Height="30" Width="100" HorizontalAlignment="Right" Content="Consultar" />
        </StackPanel>
        <Border Grid.Row="1" BorderBrush="Black" BorderThickness="1">
            <StackPanel>
                <!--ListBox que desplegará los resultados-->
                <ListBox x:Name="resultados" Height="300">
                    <ListBox.Resources>
                        <Style x:Key="titulo" TargetType="TextBlock">
                            <Setter Property="FontSize" Value="20" />
                        </Style>
                        <Style x:Key="liga" TargetType="HyperlinkButton">
                            <Setter Property="FontSize" Value="18" />
                            <Setter Property="Foreground" Value="Navy" />
                        </Style>
                    </ListBox.Resources>
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <HyperlinkButton Style="{StaticResource liga}" Content="{Binding Titulo}" NavigateUri="{Binding PaginaUrl}" />
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Border>

    </Grid>
</UserControl>

Referenciando el servicio

A nuestra aplicación Web (la cual es creada automáticamente por la plantilla de Silverlight) agregaremos una referencia a http://api.search.live.net/search.wsdl?AppID=nuestroAppId  el cual es el URL del servicio Web de búsqueda de Live Search.  Como se podrá observar necesitamos pasar como parámetro el AppID el cual es la llave mencionada con anticipación en este artículo.  A esta referencia le pondremos el nombre ServicioLiveSearch tal y como lo muestra la siguiente figura:

Ahora en nuestra aplicación Web agregaremos una clase llamada Resultado la cual represente un resultado al ejecutar la búsqueda:

public class Resultado
{
    public string Titulo { get; set; }

    public string PaginaUrl { get; set; }

    public string ImagenUrl { get; set; }


}

El siguiente paso será agregar un nuevo Servicio Web de tipo ASMX (también lo podríamos hacer con un Servicio WCF) a nuestra aplícación Web.  Este servicio tendrá el método Web Buscar() el cual recibirá como parámetro la cadena que deseamos encontrar y regresará un objeto de tipo List<Resultado> como valor de retorno tal y como se muestra en el siguiente código:

[WebMethod]
public List<Resultado> Buscar(string cadena)
{
    List<Resultado> resultados = new List<Resultado>();

    ServicioLiveSearch.LiveSearchPortTypeClient client = new SLSearch.Web.ServicioLiveSearch.LiveSearchPortTypeClient();
    SearchRequest request = new SearchRequest()
    {
        AppId="TU APP ID",
        Sources=new SourceType[]{ SourceType.Image, SourceType.Web},
        Adult= AdultOption.Moderate,
        AdultSpecified=true,
        Query=cadena
    };

    SearchResponse response = client.Search(request);
    if (response.Errors == null)
    {
        foreach (WebResult result in response.Web.Results)
        {
            resultados.Add(new Resultado() {
                Titulo = result.Title,
                PaginaUrl = result.Url
            });
        }
    }

    return resultados;
}

En el código anterior estamos instanciando la clase proxy para comunicarnos al Servicio Web de Live Search.  Posteriormente creamos un objeto de tipo SearchRequest el cual representa la petición que deseamos efectuar en el servicio de búsqueda.  Es a este objeto al cual le pasamos todos los parámetros necesarios para realizar la búsqueda.  Posteriormente, una vez ejecutada la búsqueda obtenemos los resultados en la propiedad Web.Results (o Image.Results según sea el caso).

El API de Live Search contiene toda la información acerca de los parámetros que podemos enviar al servicio según el comportamiento deseado.  Los únicos parámetros totalmente necesarios para realizar una búsqueda con Live Search son los siguientes:

  • AppID : Nuestro AppID único que se nos otorga cuando nos registramos en la liga anteriormente descrita
  • Sources :  Esta propiedad indica el tipo de búsqueda a realizar.  Es un arreglo de objetos de tipo SourceType entre los cuales podemos destacar SourceType.Web o SourceType.Image para búsquedas normales o para búsqueda de imágenes respectivamente.
  • Query : La cadena a buscar

Asimismo podemos definir algunas otras propiedades según el comportamiento que deseemos para nuestra búsqueda.  La documentación del API de Live Search contiene toda la información necesaria al respecto.

Invocando el servicio

Finalmente, en nuestra aplicación Silverlight agregamos la referencia al Servicio Web que acabamos de crear para que Visual Studio haga por nosotros todas las clases necesarias para su invocación.

Una vez realizado esto ligamos el evento Click del botón a un manejador de eventos el cual invoque el servicio pasando como parámetro la cadena a buscar.  Si la búsqueda es exitosa ataremos los resultados al ListBox que definimos en el XAML con anterioridad.  El siguiente ejemplo hace uso de expresiones Lambda en vez de definir el cuerpo de los métodos dentro de la definición de la clase:

public Page()
        {
            InitializeComponent();

            btnConsulta.Click += (s, a) =>
            {
                MiServicio.LiveSearchSoapClient client = new SLSearch.MiServicio.LiveSearchSoapClient();
                client.BuscarCompleted += (sender, args) =>
                {
                    if (args.Error == null)
                    {
                        resultados.ItemsSource = args.Result;
                    }
                };
                client.BuscarAsync(txtConsulta.Text);
            };

        }

Resultado

Listo.  Nuestra aplicación está lista para ser utilizada.  La aplicación XAP fácilmente puede ser llevada a otra aplicación en donde necesitemos este tipo de funcionalidad.

Para hacer uso de los resultados de búsqueda de imágenes necesitamos un ligero cambio en nuestro XAML en el DataTemplate del ListBox para atar el Url de la imagen encontrada a un elemento de tipo Image:

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <Image Source="{Binding ImagenUrl}" Width="100" />
        <HyperlinkButton Style="{StaticResource liga}" Content="{Binding Titulo}" NavigateUri="{Binding PaginaUrl}" />
    </StackPanel>
</DataTemplate>

Y en el Servicio Web usamos Image.Results:

SearchResponse response = client.Search(request);
if (response.Errors == null)
{
    foreach (ImageResult result in response.Image.Results)
    {
        resultados.Add(new Resultado() {
            Titulo = result.Title,
            PaginaUrl = result.Url,
            ImagenUrl= result.MediaUrl
        });
    }
}

Resultado:

Pueden descargar el código fuente de este ejemplo haciendo clic aquí o directamente en la sección “Contenido” de La Liga Silverlight.