Thursday, March 25, 2010

Wrapping up the "Bing API 2.0" series

Today I posted the last post in the "Bing API 2.0" series.

I hope I showed you that using this API isn't hard, but very simple and straightforward.

You can find the complete series here:If you want more information/documentation on the Bing API, I advice you to look for it in the Bing Developer Center.

Do you have any cool applications in mind which you can build on top of the Bing API?

Bing API 2.0: Consume results with SOAP using .NET

Compared to XML, using SOAP in .NET has some advantages.

Advantage

There is less XML processing to do, since the web services infrastructure in .NET handles deserializing the SOAP XML responses from the SOAP interfaces into strongly-typed .NET collections.

Example

The first thing you need to do is add a Web Reference in Visual Studio using the Bing WSDL. The WSDL can be found at http://api.search.live.net/search.wsdl. By adding this web reference, Visual Studio generates some classes based on this WSDL, which we can use to query Bing.

In this example, I create a new LiveSearchPortTypeClient, create a SearchRequest and pass that SearchRequest to the Search method of the LiveSearchPortTypeClient. This returns a SearchResponse. And now it's really easy to display the results. Just look in the SearchResponse properties and pick what you need.

   1:  namespace BingAPIConsumeSOAP
   2:  {
   3:      class Program
   4:      {
   5:          static void Main(string[] args)
   6:          {             
   7:              LiveSearchPortTypeClient client = new LiveSearchPortTypeClient();            
   8:              SearchRequest req = new SearchRequest();            
   9:              req.AppId = "[YourAppId]";
  10:              req.Sources = new SourceType[] { SourceType.Image} ;
  11:              req.Query = "Mini Cooper S";
  12:   
  13:              SearchResponse resp = client.Search(req);
  14:   
  15:              foreach (var res in resp.Image.Results)
  16:              {
  17:                  Console.WriteLine(res.Title);
  18:                  Console.WriteLine(res.MediaUrl);
  19:                  Console.WriteLine(Environment.NewLine);
  20:              }
  21:   
  22:              Console.ReadLine();
  23:          }
  24:      }
  25:  }


This post is part of the Bing API 2.0 series.

Wednesday, March 24, 2010

Bing API 2.0: Consume results as XML with .NET

In the post 'Get Started' I told you that you can use HTTP GET to send requests. This means that we can send the HTTP request and get the response using .NET as well.

An example

In this example I use an HttpWebRequest to create a request and an HttpWebResponse to get the response. You can find these classes in the System.Net namespace.

   1:  namespace BingAPIConsumeXML
   2:  {
   3:      class Program
   4:      {
   5:          static void Main(string[] args)
   6:          {
   7:              string url = "http://api.search.live.net/xml.aspx?AppId=[YourAppId]&query=Mini+Cooper+S&sources=image";
   8:   
   9:              //Request and get the Response
  10:              HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
  11:              HttpWebResponse resp = (HttpWebResponse)req.GetResponse();          
  12:                       
  13:              //Write the Byte Array to the console as a string
  14:              StreamReader reader = new StreamReader(resp.GetResponseStream());
  15:              string res = reader.ReadToEnd();
  16:   
  17:              Console.WriteLine(res);
  18:   
  19:              Console.ReadLine();
  20:          }
  21:      }
  22:  }

You can parse the XML response using your favorite .NET parsing method.

In this example I simple load the ResponseStream into a StreamReader and write the Stream to a string.


This post is part of the Bing API 2.0 series.

Tuesday, March 23, 2010

Bing API 2.0: Consume results as JSON using Javascript

It's pretty easy to consume JSON returned from the Bing API using Javascript. There is one tricky part though.

JSONP

Browsers don't let you use JSON results from another website due to security restrictions. By dynamically adding a script tag on your page, you can workaround this restriction though. This technique is called JSONP. More information on JSONP can be found on Rick Strahl's blog.

jQuery makes using JSONP relatively easy. The getJSON method does all the hardcore scripting for you. All you need to supply is the url and and a callback function.

The url

In the previous post, we chose the XML format to display our results. We can reuse the url from the previous post, by simply replacing xml.aspx with json.aspx. In this example our url looks like this: http://api.search.live.net/json.aspx?AppId=[YourAppId]&query=Mini+Cooper+S&sources=image

Showing our results

With a little help from our friend jQuery, it's easy to display some results.

When the document is ready, I get the results in a JSON format from the Bing API. I pass in a callback function. This callback function takes the results, loops over the Image results and adds them as an image to a div.

The code looks something like this..

   1:  <html>
   2:  <head>
   3:      <script src="http://code.jquery.com/jquery-latest.js"></script>
   4:      <script type="text/javascript">
   5:          $(document).ready(function(){
   6:              $.getJSON("http://api.search.live.net/json.aspx?AppId=[YourAppId]&query=Mini+Cooper+S&sources=image", 
   7:                  function(data){
   8:                      $.each(data.SearchResponse.Image.Results, function(i, item){                                            
   9:                          $("<img/>").attr("src", item.MediaUrl)                                                                   
  10:                                     .appendTo("#images")
  11:                                     .wrap("<a href='" + item.Url + "'></a>")                                                 
  12:                      });
  13:                  });
  14:          });
  15:      </script>
  16:  </head>
  17:  <body>
  18:      <div id="images"></div>
  19:  </body>
  20:  </html>

And the result looks like this.



Sweet, right?

This post is part of the Bing API 2.0 series.

Sunday, March 21, 2010

Bing API 2.0: Get started

Getting an AppId

The first thing you need is an ApplicationId. The ApplicationId enables the API to validate that a request is from a registred Bing application developer.

You can request your ApplicationId at the Bing Developer Center.

Getting your first results

Next to the ApplicationId, the API requires the Query and Sources parameters. The Query parameter is the text of the query. The Sources parameter is one or more values indicating the SourceTypes you require. An overview of available SourceTypes can be found on MSDN.

You can use HTTP GET to send requests, meaning you can use your browser to get a feel of the API.

Here is how I built my first request..

I wanted to search for images for the query 'Mini Cooper S'. My url looked something like this: http://api.search.live.net/xml.aspx?AppId=[YourAppId]&query=Mini+Cooper+S&sources=image

And the result looked like this.


The results returned include a header and a results body. The document element is always a SearchResponse, with a Query child element that contains the query used to produce the results. The results body follows the header. The body contains the results per SourceType you specify in the url.

This post is part of the Bing API 2.0 series.

Presenting the "Bing API 2.0" series

Not so long ago Microsoft released Version 2 of the Bing API.

The Bing API enables you to create a flexible and powerful custom search component in your sites and applications. Because the Bing API supports multiple formats, you can consume the results with your favorite technology. Formats supported by the API are: XML, JSON, SOAP and RSS.

In these series I'll show you how to:
  • Get started
  • Consume results as JSON with Javascript
  • Consume results as XML with .NET
  • Consume results using SOAP with .NET

Monday, March 15, 2010

Quick and dirty tool for sending UDP packets

While I was playing with my UDPListener I needed a small tool which could send some UDP packets to a certain hostname and port. That's why I wrote a console application which uses an UdpClient to send some UDP packets. It's quick and dirty, but it serves the cause.

   1:  namespace UdpSender
   2:  {
   3:      class Program
   4:      {
   5:          //Constants
   6:          private const string HOSTNAME = "LocalHost";
   7:          private const int PORT = 800;
   8:          private const int TIMES = 5;
   9:          private const string MESSAGE = "This is a TestMessage";
  10:          private const int SLEEP = 50;
  11:   
  12:          static void Main(string[] args)
  13:          {
  14:              using (UdpClient client = new UdpClient())
  15:              {
  16:                  //Connect
  17:                  client.Connect(HOSTNAME, PORT);
  18:                  Console.WriteLine(string.Format("Connected to {0}:{1}.", HOSTNAME, PORT));
  19:                  Console.WriteLine("Start sending packets..");
  20:   
  21:                  //Send packets
  22:                  int timesSent = 0;
  23:                  while (timesSent < TIMES)
  24:                  {
  25:                      timesSent++;
  26:   
  27:                      //Convert the message to a Byte array
  28:                      Byte[] mess = Encoding.ASCII.GetBytes(MESSAGE);
  29:   
  30:                      //Send the message
  31:                      client.Send(mess, mess.Count());
  32:   
  33:                      Console.WriteLine(string.Format("Message {0} sent..", timesSent));
  34:                      //Sleep for a while
  35:                      Thread.Sleep(SLEEP);
  36:                  }
  37:   
  38:                  //Close the client
  39:                  client.Close();
  40:              }
  41:   
  42:              Console.WriteLine("Finished sending packets..");
  43:              Console.ReadLine();
  44:          }
  45:      }
  46:  }


You can download the source here.

Sunday, March 14, 2010

Listening for UDP packets in a Windows service using an UdpClient

In this post, I'll show you how can you listen for UDP packets in a Windows service.

OnStart

When the service starts, I set the started flag to true, initialize the ManualResetEvent, initialize an UdpClient and a WorkingThread. The ManualResetEvent will help us on a later stage to make our service stop elegantly.

   1:  protected override void OnStart(string[] args)
   2:  {
   3:       Start();
   4:  }
   5:       
   6:  public void Start()
   7:  {
   8:       m_started = true;
   9:   
  10:       m_stop = new ManualResetEvent(false);
  11:   
  12:       InitializeUdpListener();
  13:       InitializeWorkingThread();
  14:  }

Initializing

First we need to initialize an IPEndpoint. When the IPEndpoint is initialized we can initialize the UdpClient using that IPEndpoint.

   1:  private void InitializeUdpClient()
   2:  {
   3:       m_endPoint = new IPEndPoint(IPAddress.Any, PORT_NUMBER);            
   4:       m_client = new UdpClient(m_endPoint);
   5:  }

After initializing our UdpClient, we can initialize and start the WorkingThread.

   1:  private void InitializeWorkingThread()
   2:  {
   3:       m_workingThread = new Thread(WorkerFunction);
   4:       m_workingThread.Name = "WorkingThread";
   5:       m_workingThread.Start();
   6:  }


WorkerFunction

The WorkerFunction does all the work.

While the service is started, we start receiving packets. We pass in an AsyncCallback Delegate which is called when the asynchronous operation completes. In this delegate we make sure that the result we receive is complete. If the result is complete we end receiving and get the content of the UDP packet.

Finally we use the WaitHandle to wait for either the asynchronous operation to complete or the workerthread to grant a termination request through the stop ManualResetEvent.

   1:  private void WorkerFunction()
   2:  {
   3:       while (m_started)
   4:       {
   5:           //BeginReceive starts an asynchronous operation, in reality to allow us to achieve
   6:           //semi-synchronous invocation, where we wait for either the asynchronous operation
   7:           //to complete or the worker thread to grant a termination request through stop
   8:           var res = m_client.BeginReceive(iar =>
   9:           {
  10:                if (iar.IsCompleted)
  11:                {
  12:                     byte[] receivedBytes = m_client.EndReceive(iar, ref m_endPoint);
  13:                     string receivedPacket = Encoding.ASCII.GetString(receivedBytes);
  14:                }
  15:            }, null);
  16:   
  17:            if (WaitHandle.WaitAny(new[] { m_stop, res.AsyncWaitHandle }) == 0)
  18:            {
  19:                break;
  20:            }
  21:       }
  22:  }        

OnStop

In the OnStop event we need to set the ManualResetEvent, so our WorkerFunction can exit gracefully.

   1:  protected override void OnStop()
   2:  {
   3:      m_stop.Set();
   4:      m_started = false;
   5:  }

I'm pretty sure this is a robust solution. A service based on this example deployed to production has been handling 1000 packets an hour on average for the last three weeks without problems.

Thanks to Bart De Smet for helping me out with the threading stuff!

You can download the source here.

Saturday, March 13, 2010

Cannot Start Service from the command line or debugger. A Windows Service must first be installed (using installutil.exe)..

When you create a new Windows Service project and try to debug it, Visual Studio will show you a Windows Service Start Failure with the message "Cannot Start Service from the command line or debugger. A Windows Service must first be installed (using installutil.exe) and then started with the Server Explorer, Windows Services Administrative tool or the NET START command.".


The trick my team and I use to workaround this problem, makes use of the service Debug flag. If the Debug flag is on, we just start the service by using our own public Start method. When the OnStart event is fired in the service itself, we call the same public Start method.

This goes in your service.

   1:  protected override void OnStart(string[] args)
   2:  {
   3:       Start();
   4:  }
   5:       
   6:  public void Start()
   7:  {
   8:       //Start!
   9:  }


And this goes in Program.cs.

   1:  namespace UdpListener
   2:  {
   3:      static class Program
   4:      {
   5:          /// <summary>
   6:          /// The main entry point for the application.
   7:          /// </summary>
   8:          static void Main()
   9:          {
  10:  #if (!DEBUG)
  11:              ServiceBase[] ServicesToRun;
  12:              ServicesToRun = new ServiceBase[] 
  13:              { 
  14:                  new UdpListener() 
  15:              };
  16:              ServiceBase.Run(ServicesToRun);
  17:  #else
  18:              UdpListener listener = new UdpListener();
  19:              listener.Start();
  20:  #endif           
  21:          }
  22:      }
  23:  }

You can set the Debug flag of your service in your service properties.



The only problem with this solution is that you can't debug your OnStop event but this hasn't been an issue for us so far.

Other ways to solve this issue can be found here:
- MSDN: How to: Debug Windows Service Applications
- KB824344: How to debug Windows services
- MSDN: How to: Launch the Debugger Automatically