Walkthrough: Using BING Service over SOAP Protocol in a Console Application

Introduction

This walkthrough shows how to use the BING features as a Web service in a client console application. This service, that we'll call BING Service, is invoked by the client console application using SOAP protocol over HTTP. You can also use XML and JSON to invoke the service. We'll have related examples at a later time.

BING Service Background

Complex problems such as indexing, relevance logic, and hosting issues such as CPU and storage are solved in transparent way to your application by having the ability to use the BING features as a Web service. This article offers a starting point for adding the service to your application.

Remember that a Web service is a component on a Web server that a client application can call by making HTTP requests across the Web. If you want some good explanation about this subject, see this MSDN article Using ASP.NET Web Services.

By using the service you can integrate the following features in your application:

  • Retrieve information from the Internet.
  • Add advertisements to your application.
  • Improve and enhance search requests and results.
  • Find location-specific information.
  • Translate terms and blocks of text.

You interact with the BING Service through the BING API

Each of the previous feature is associated with one or more Bing API SourceTypes. A SourceType is a source of information accessible via the BING API.   An overall description of these SourceTypes can be find on MSDN at this location: About the Bing API.

Prerequisites

In order to complete the example in this topic, you need the following:

  • Visual Studio 2010.
  • The ability to send requests using the Simple Object Access Protocol (SOAP) 1.1 and the Hyper Text Transfer Protocol (HTTP 1.1)
  • The ability to parse SOAP and XML

Creating a Console Application

This section shows how to create a console application that will use the BING Service.

To create a console application

  1. Start Visual Studio.
  2. In the File menu, click New, and then click Project.
  3. The New Project dialog box is displayed.
  4. Under Installed Templates, in the left pane, select Visual C# (or Visual Basic).
  5. Then select Windows.
  6. In the right pane, select Console Application.
  7. In the Location box enter the name of the folder where you want to keep the Web application. For example, enter the folder name C:\CS\SOAP\ConsoleApplications
  8. In the Name box enter the name of the project. For example, enter the name UsingBingAPI.
  9. Click OK.
  10. A console application is created. Rename the file Program.cs to UsingBingAPI.cs.

Adding a Web Reference to BING Service

This section shows how to add a Web reference to the BING Service. In order to do that, you use a Web service discovery process by which the client application locates the service and obtains its description. The process of Web service discovery in Visual Studio involves interrogating a Web site to locate the service description, which is an XML document that uses the Web Services Description Language (WSDL).

When you add a Web reference to a project, Visual Studio generates a proxy class that provides a local representation of the Web service, which allows the client code to interface with the Web service. You can access Web service methods by calling the methods in the proxy class. The proxy class handles the communication between the client application and the Web service itself.

To add a Web reference to BING Service

  1. In Solution Explorer , right-click the project name, and then click Add Service Reference  button.
  2. In the Add Service Reference dialog box, click the Advanced...  button.
  3. In the Service Reference Settings  dialog box, click the Add Web Reference... button.
  4. In the URL  box enter the following value: https://api.search.live.net/search.wsdl.
  5. Click GO .
  6. If the process has been added successfully a message is displayed saying that "1 Service Found: Search" and the Web reference is: net.live.search.api.
  7. Click Add Reference... button.
  8. A Web References folder is added to the project that contains the reference to the live search service.
  9. Also, the app.config file is created and added to the project. This file contains address information about the soap.asmx service.

 

Adding Code to the Console Application to Interact with BING Service

This section shows the code that provides an interactive menu that enables the user to choose the desired BING service type. Also it shows the code that enables the application to interact with the BING service types. For simplicity only the following types are provided:

SourceType Function
Web Retrieve information from the Internet
InstantAnswer Retrieve information from the Internet
Phonebook Find location specific information

 

To create the user dialog

This section shows how to create the code to provide an interactive menu that enables the user to choose the desired BING service type.

  1. In Solution Explorer , open the file  UsingBingAPI.cs. and add the code shown next.

The code provides an interactive menu that enables the user to choose the desired BING service type among the three listed before.

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace UsingBingAPI
{
    #region ApplicationMain

    class ApplicationMain
    {
        // Display user's menu.
        public static void UserMenu()
        {
            StringBuilder buffer = new StringBuilder();

            buffer.AppendLine("Please, make your selection.");
            buffer.AppendLine("1    -- Using Web SourceType.");
            buffer.AppendLine("2    -- Using InstantAnswer SourceType.");
            buffer.AppendLine("3    -- Using Phonebook SourceType.");
            buffer.AppendLine("?    -- Display help.");
            buffer.AppendLine("Q,q  -- Exit the application.");

            Console.Write(buffer.ToString());
        }

        // Obtain user's input and provide
        // feedback.
        static void Main(string[] args)
        {
            // Define user selection string.
            string selection;

            // Get user selection.
            while (true)
            {

                UserMenu();
                Console.Write("> ");
                selection = Console.ReadLine();
                if (selection != string.Empty)
                    break;
            }

            while (selection.ToLower() != "q")
            {
                // Process user's input.
                switch (selection)
                {
                    case "1":
                        // Demonstrate the use of the
                        // Web SourceType over the SOAP Protocol.
                        WebSample.WebType();
                        break;

                    case "2":
                        // Demonstrate the use of the
                        // InstantAnswer SourceType over the SOAP Protocol.
                        InstantAnswerFlightStatusSample.Flight();
                        break;

                    case "3":
                        // Demonstrate the use of the
                        // Phonebook SourceType over the SOAP Protocol.
                        PhonebookSample.Phone();
                        break;

                    default:
                        UserMenu();
                        break;
                }
                Console.Write("> ");
                selection = Console.ReadLine();
            }
        }
    }
    #endregion ApplicationMain
}

To create the code to use with BING Service Web Type

This section shows how to create the code that enable the application to use BING Service Web type. For more information, see  WebRequest Class, WebResponse Class and WebResult Class. Remember that you need to obtain your AppID and assign it to the AppId constant string, in the code shown next. You obtain the AppID from the BING Developer Center.

  1. In Solution Explorer , create the file  WebSample.cs. and add the code shown next. The code demonstrates the use of the Web SourceType over the SOAP Protocol.
  2. Save and close the file.
 using System;
using System.Xml;

// This using directive assumes that the project's default namespace is
// "UsingBingAPI" and the name of the Bing API web reference is
// "net.live.search.api". Modify this using directive as necessary.
using UsingBingAPI.net.live.search.api;

// Bing API 2.1 code sample demonstrating the use of the
// Web SourceType over the SOAP Protocol.
static class WebSample
{
    // Replace the following string with the AppId you received from the
    // Bing Developer Center.
    const string AppId = "Enter your AppID";

    static public void WebType()
    {
        // LiveSearchService implements IDisposable.
        using (LiveSearchService service = new LiveSearchService())
        {
            try
            {
                SearchRequest request = BuildRequest();

                // Send the request; display the response.
                SearchResponse response = service.Search(request);
                DisplayResponse(response);
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                // A SOAP Exception was thrown. Display error details.
                DisplayErrors(ex.Detail);
            }
            catch (System.Net.WebException ex)
            {
                // An exception occurred while accessing the network.
                Console.WriteLine(ex.Message);
            }
        }
    }

    static SearchRequest BuildRequest()
    {
        SearchRequest request = new SearchRequest();

        // Common request fields (required)
        request.AppId = AppId;
        request.Query = "msdn blogs";
        request.Sources = new SourceType[] { SourceType.Web };

        // Common request fields (optional)
        request.Version = "2.0";
        request.Market = "en-us";
        request.Adult = AdultOption.Moderate;
        request.AdultSpecified = true;
        request.Options = new SearchOption[]
        {
            SearchOption.EnableHighlighting
        };

        // Web-specific request fields (optional)
        request.Web = new WebRequest();
        request.Web.Count = 10;
        request.Web.CountSpecified = true;
        request.Web.Offset = 0;
        request.Web.OffsetSpecified = true;
        request.Web.Options = new WebSearchOption[]
        {
            WebSearchOption.DisableHostCollapsing,
            WebSearchOption.DisableQueryAlterations
        };

        return request;
    }

    static void DisplayResponse(SearchResponse response)
    {
        // Display the results header.
        Console.WriteLine("Bing API Version " + response.Version);
        Console.WriteLine("Web results for " + response.Query.SearchTerms);
        Console.WriteLine(
            "Displaying {0} to {1} of {2} results",
            response.Web.Offset + 1,
            response.Web.Offset + response.Web.Results.Length,
            response.Web.Total);
        Console.WriteLine();

        // Display the Web results.
        System.Text.StringBuilder builder = new System.Text.StringBuilder();
        foreach (WebResult result in response.Web.Results)
        {
            builder.Length = 0;
            builder.AppendLine(result.Title);
            builder.AppendLine(result.Description);
            builder.AppendLine(result.Url);
            builder.Append("Last Crawled: ");
            builder.AppendLine(result.DateTime);

            DisplayTextWithHighlighting(builder.ToString());
            Console.WriteLine();
        }
    }

    static void DisplayTextWithHighlighting(string text)
    {
        // Write text to the standard output stream, changing the console
        // foreground color as highlighting characters are encountered.
        foreach (char c in text.ToCharArray())
        {
            if (c == '\uE000')
            {
                // If the current character is the begin highlighting
                // character (U+E000), change the console foreground color
                // to green.
                Console.ForegroundColor = ConsoleColor.Green;
            }
            else if (c == '\uE001')
            {
                // If the current character is the end highlighting
                // character (U+E001), revert the console foreground color
                // to gray.
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            else
            {
                Console.Write(c);
            }
        }
    }

    static void DisplayErrors(XmlNode errorDetails)
    {
        // Add the default namespace to the namespace manager.
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(
            errorDetails.OwnerDocument.NameTable);
        nsmgr.AddNamespace(
            "api",
            "https://schemas.microsoft.com/LiveSearch/2008/03/Search");

        XmlNodeList errors = errorDetails.SelectNodes(
            "./api:Errors/api:Error",
            nsmgr);

        if (errors != null)
        {
            // Iterate over the list of errors and display error details.
            Console.WriteLine("Errors:");
            Console.WriteLine();
            foreach (XmlNode error in errors)
            {   
                foreach (XmlNode detail in error.ChildNodes)
                {
                    Console.WriteLine(detail.Name + ": " + detail.InnerText);
                }

                Console.WriteLine();
            }
        }
    }
}

 

To create the code to use with BING Service InstantAnswer Type

This section shows how to create the code that enable the application to use BING Service InstantAnswer type. For more information, see InstantAnswerResponse Class and InstantAnswerResult Class.

Remember that you need to obtain your AppID and assign it to the AppId constant string, in the code shown next. You obtain the AppID from the BING Developer Center.

  1. In Solution Explorer , create the file  InstantAnswerFlightStatusSample.cs. and add the code shown next. The code demonstrates the use of the InstantAnswer SourceType that returns FlightStatus results over the SOAP Protocol.
  2. Save and close the file.
 using System;
using System.Xml;

// This using directive assumes that the project's default namespace is
// "UsingBingAPI" and the name of the Bing API web reference is
// "net.live.search.api". Modify this using directive as necessary.
using UsingBingAPI.net.live.search.api;

// Bing API 2.2 code sample demonstrating the use of the
// InstantAnswer SourceType to return FlightStatus results over the SOAP Protocol.
static class InstantAnswerFlightStatusSample
{
    // Replace the following string with the AppId you received from the
    // Bing Developer Center.
    const string AppId = "Enter your AppID";

    static public void Flight()
    {
        // LiveSearchService implements IDisposable.
        using (LiveSearchService service = new LiveSearchService())
        {
            try
            {
                SearchRequest request = BuildRequest();

                // Send the request; display the response.
                SearchResponse response = service.Search(request);
                DisplayResponse(response);
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                // A SOAP Exception was thrown. Display error details.
                DisplayErrors(ex.Detail);
            }
            catch (System.Net.WebException ex)
            {
                // An exception occurred while accessing the network.
                Console.WriteLine(ex.Message);
            }
        }
    }

    static SearchRequest BuildRequest()
    {
        SearchRequest request = new SearchRequest();

        // Common request fields (required)
        request.AppId = AppId;
        request.Query = "CO234";
        request.Sources = new SourceType[] { SourceType.InstantAnswer };

        // Common request fields (optional)
        request.Version = "2.2";
        request.Market = "en-us";
        return request;
    }

    static void DisplayResponse(SearchResponse response)
    {
        // Display the results header.
        Console.WriteLine("Bing API Version " + response.Version);
        Console.WriteLine(
            "InstantAnswer results for \"" + response.Query.SearchTerms + "\" query");
        Console.WriteLine();

        // Display the InstantAnswer results.
        foreach (InstantAnswerResult result in response.InstantAnswer.Results)
        {
            Console.WriteLine(
                "Title: " + result.Title);
            Console.WriteLine(
                "ClickThroughUrl: " + result.ClickThroughUrl);
            Console.WriteLine(
                "URL: " + result.Url);
            Console.WriteLine(
                System.Environment.NewLine + "InstantAnswerSpecificData for FlightStatus");
            DisplayInstantAnswerSpecificData(result.InstantAnswerSpecificData);
            Console.WriteLine();          
        }
    }

    static void DisplayInstantAnswerSpecificData(string data)
    {
        // Load the InstantAnswer-specific data into an XmlDocument.
        XmlDocument document = new XmlDocument();
        document.Load(new System.IO.StringReader(data));

        // Add the FlightStatus namespace to the namespace manager.
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(
            document.NameTable);
        nsmgr.AddNamespace(
            "fls",
            "https://schemas.microsoft.com/LiveSearch/2008/04/XML/element/flightstatus");

        string flightName = document.DocumentElement.SelectSingleNode(
    "./fls:FlightName",
    nsmgr).InnerText;

        Console.WriteLine(
            "Flight: " + flightName);

        string statusString = document.DocumentElement.SelectSingleNode(
            "./fls:StatusString",
            nsmgr).InnerText;

        Console.WriteLine(
            "Status: " + statusString);

        string originAirportName = document.DocumentElement.SelectSingleNode(
    "./fls:OriginAirport/fls:Name",
    nsmgr).InnerText;

        Console.WriteLine(
            "From: " + originAirportName);


        string destinationAirportName = document.DocumentElement.SelectSingleNode(
    "./fls:DestinationAirport/fls:Name",
    nsmgr).InnerText;

        Console.WriteLine(
            "To: " + destinationAirportName);



        string scheduledDeparture = document.DocumentElement.SelectSingleNode(
    "./fls:ScheduledDeparture",
    nsmgr).InnerText;

        Console.WriteLine(
            "Scheduled Departure: " + scheduledDeparture);


        string scheduledArrival = document.DocumentElement.SelectSingleNode(
    "./fls:ScheduledArrival",
    nsmgr).InnerText;

        Console.WriteLine(
            "Scheduled Arrival: " + scheduledArrival);

    }

    static void DisplayErrors(XmlNode errorDetails)
    {
        // Add the default namespace to the namespace manager.
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(
            errorDetails.OwnerDocument.NameTable);
        nsmgr.AddNamespace(
            "api",
            "https://schemas.microsoft.com/LiveSearch/2008/03/Search");

        XmlNodeList errors = errorDetails.SelectNodes(
            "./api:Errors/api:Error",
            nsmgr);

        if (errors != null)
        {
            // Iterate over the list of errors and display error details.
            Console.WriteLine("Errors:");
            Console.WriteLine();
            foreach (XmlNode error in errors)
            {
                foreach (XmlNode detail in error.ChildNodes)
                {
                    Console.WriteLine(detail.Name + ": " + detail.InnerText);
                }
                Console.WriteLine();
            }
        }
    }
}

 

To create the code to use with BING Service Phonebook Type

This section shows how to create the code that enable the application to use BING Service Phonebooktype. For more information, see  PhonebookRequest Class, PhonebookResponse Class and PhonebookResult Class.

Remember that you need to obtain your AppID and assign it to the AppId constant string, in the code shown next. You obtain the AppID from the BING Developer Center.

  1. In Solution Explorer , create the file PhonebookSample.cs. and add the code shown next. The code demonstrates the use of the Phonebook SourceType over the SOAP Protocol.
  2. Save and close the file.
 using System;
using System.Xml;

// This using directive assumes that the project's default namespace is
// "UsingBingAPI" and the name of the Bing API web reference is
// "net.live.search.api". Modify this using directive as necessary.
using UsingBingAPI.net.live.search.api;

// Bing API 2.0 code sample demonstrating the use of the
// Phonebook SourceType over the SOAP Protocol.
static class PhonebookSample
{
    // Replace the following string with the AppId you received from the
    // Bing Developer Center.
    const string AppId = "Enter your AppID";

    static public void Phone()
    {
        // LiveSearchService implements IDisposable.
        using (LiveSearchService service = new LiveSearchService())
        {
            try
            {
                SearchRequest request = BuildRequest();

                // Send the request; display the response.
                SearchResponse response = service.Search(request);
                DisplayResponse(response);
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                // A SOAP Exception was thrown. Display error details.
                DisplayErrors(ex.Detail);
            }
            catch (System.Net.WebException ex)
            {
                // An exception occurred while accessing the network.
                Console.WriteLine(ex.Message);
            }
        }
    }

    static SearchRequest BuildRequest()
    {
        SearchRequest request = new SearchRequest();

        // Common request fields (required)
        request.AppId = AppId;
        request.Query = "microsoft offices";
        request.Sources = new SourceType[] { SourceType.Phonebook };

        // Common request fields (optional)
        request.Version = "2.0";
        request.Market = "en-us";
        request.UILanguage = "en";
        request.Latitude = 47.603450;
        request.LatitudeSpecified = true;
        request.Longitude = -122.329696;
        request.LongitudeSpecified = true;
        request.Radius = 10.0;
        request.RadiusSpecified = true;
        request.Options = new SearchOption[]
        {
            SearchOption.EnableHighlighting
        };

        // Phonebook-specific request fields (optional)
        request.Phonebook = new PhonebookRequest();
        request.Phonebook.Count = 10;
        request.Phonebook.CountSpecified = true;
        request.Phonebook.Offset = 0;
        request.Phonebook.OffsetSpecified = true;
        request.Phonebook.FileType = "YP";
        request.Phonebook.SortBy = PhonebookSortOption.Distance;
        request.Phonebook.SortBySpecified = true;

        return request;
    }

    static void DisplayResponse(SearchResponse response)
    {
        // Display the results header.
        Console.WriteLine("Bing API Version " + response.Version);
        Console.WriteLine(
            "Phonebook results for " + response.Query.SearchTerms);
        Console.WriteLine(
            "Displaying {0} to {1} of {2} results",
            response.Phonebook.Offset + 1,
            response.Phonebook.Offset + response.Phonebook.Results.Length,
            response.Phonebook.Total);
        Console.WriteLine();

        // Display the Phonebook results.
        System.Text.StringBuilder builder = new System.Text.StringBuilder();
        foreach (PhonebookResult result in response.Phonebook.Results)
        {
            builder.Length = 0;
            builder.AppendLine(result.Business);
            builder.AppendLine(result.Address);
            builder.Append(result.City);
            builder.Append(", ");
            builder.AppendLine(result.StateOrProvince);
            builder.AppendLine(result.PhoneNumber);
            builder.Append("Average Rating: ");
            builder.AppendLine(result.UserRating.ToString());

            DisplayTextWithHighlighting(builder.ToString());
            Console.WriteLine();
        }
    }

    static void DisplayTextWithHighlighting(string text)
    {
        // Write text to the standard output stream, changing the console
        // foreground color as highlighting characters are encountered.
        foreach (char c in text.ToCharArray())
        {
            if (c == '\uE000')
            {
                // If the current character is the begin highlighting
                // character (U+E000), change the console foreground color
                // to green.
                Console.ForegroundColor = ConsoleColor.Green;
            }
            else if (c == '\uE001')
            {
                // If the current character is the end highlighting
                // character (U+E001), revert the console foreground color
                // to gray.
                Console.ForegroundColor = ConsoleColor.Gray;
            }
            else
            {
                Console.Write(c);
            }
        }
    }

    static void DisplayErrors(XmlNode errorDetails)
    {
        // Add the default namespace to the namespace manager.
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(
            errorDetails.OwnerDocument.NameTable);
        nsmgr.AddNamespace(
            "api",
            "https://schemas.microsoft.com/LiveSearch/2008/03/Search");

        XmlNodeList errors = errorDetails.SelectNodes(
            "./api:Errors/api:Error",
            nsmgr);

        if (errors != null)
        {
            // Iterate over the list of errors and display error details.
            Console.WriteLine("Errors:");
            Console.WriteLine();
            foreach (XmlNode error in errors)
            {   
                foreach (XmlNode detail in error.ChildNodes)
                {
                    Console.WriteLine(detail.Name + ": " + detail.InnerText);
                }

                Console.WriteLine();
            }
        }
    }
}

 

Testing the Console Application

This section shows the steps to perform to test the application.

  1. Build the application.
  2. In a command Window go to the folder where the UsingBingAPI.exe file is located. Most likely the Debug folder.
  3. Execute the following command: >UsingBingApi.
  4. A dialog is displayed.
  5. Make a selection as suggested by the dialog.
  6. The selected BING service type is invoked and the related results shown.

We are done.

A complete Visual Studio project is attached next. Please download and play with it.

I appreciate your feedback.

See Also

Bing API, Version 2

Working with Protocols (Bing, Version 2)

Working with SourceTypes (Bing, Version 2)

UsingBingAPI.zip