Export (0) Print
Expand All

Consuming "Dallas" OData with Managed Code

This topic describes how to consume data from “Dallas” with an OData endpoint in applications using managed code.

Introduction

“Dallas” is in its third Community Technology Preview (CTP). CTP3 introduces live OData services. To learn more about the differences between CTP3 OData based services and CTP2 based services visit the “Dallas” team blog.

Accessing “Dallas” OData requires adding a “service reference” to your Visual Studio project. Service references are specific to particular datasets. The code in a service reference should not be modified as modification could result in improper functioning and side effects. Additionally, modifications will be overwritten whenever your service reference is refreshed. If accessing multiple data sources you need to add a service reference for each data source.

Prerequisites

This section assumes that you have a “Dallas” account and have completed Lessons 1 through 3 in the section Working with "Dallas" Accounts and Subscriptions and are familiar with the “Dallas” Marketplace and Service Explorer. You also need a subscription to InfoGroup’s InfoUSA New, Out-Of-Business and Historical Businesses - InfoUSA CTP3 service.

Step 1: Starting Your Project

  1. Start Visual Studio as an Administrator

    1. Right click Visual Studio in your Start Menu and select Run as administrator.

    2. When asked if you want to allow this program (devenv.exe) to make changes to your computer click Yes.

  2. On the Visual Studio Start Page select New Project.

  3. From the New Project dialog box select C# Console Application. Give your project a meaningful name. For example, for this project you could name it InfoUSABusinessData. Then click OK.

  4. Add the following using statement to Program.cs.

    
    using System.Net;  // Needed for authentication
    
    

Step 2: Adding a Service Reference to Your Application

After starting Visual Studio as an administrator and creating a new console application (Step 1) add the service reference for the data you want to consume.

  1. Sign in to your Windows Live Id.

  2. Get the URL for the service you want to use.

    1. Go to the “Dallas” Marketplace and select the Subscriptions tab.

    2. Find the InfoUSA New, Out-Of-Business and Historical Businesses - InfoUSA service and click Click here to explore the dataset.

    3. Scroll to the bottom of the page and find the text Create client classes by adding a service reference in Microsoft Visual Studio. Copy the link below it to your clipboard.

      Service Reference URL

  3. Add a service reference to your Visual Studio project

    1. Return to your Visual Studio project. In Solution Explorer right click References. Select Add Service Reference… from the dropdown menu.

      WarningWarning
      This only works in Microsoft® Visual Studio.

      Add Service Reference in Visual Studio

    2. Paste the URL you copied to your clipboard above into the Address dropdown. Click Go. Wait a few moments for the Services text box to populate with the services available to your project.

    3. Click the Namespace: textbox. Give it a meaningful namespace name. For example, InfoUSABusinesses. Click OK.

      This adds a Service Reference node to your project in Solution Explorer with this service reference under it.

      In the image below the red oval is the URL you pasted in for your service, the blue oval is the name of the service available at this URL, and the green oval is the namespace name you create.

      Visual Studio Service Reference Dialog
  4. Add the service reference to your code.

    1. Open Program.cs in the Visual Studio code window.

    2. Add the following using statement which makes your service reference accessible to your application.

      Author's Note: InfoUSABusinessData is the name you chose as your project name/namespace. InfoUSABusinesses is the namespace name you chose when you added the service reference.

      
      using InfoUSABusinessData.InfoUSABusinesses; // RESTful proxy to data
      
      

Step 3: Consuming OData with Managed Code

  1. Within your project’s namespace create a public class, GetBusinessData. This class consumes the business data from the InfoUSA New, Out-of-Business and Historical Bussinesses – InfoUSA service.

  2. Create two private variables for your class.

    1. A Uri to the service and a service container that stores your credentials in service context.

      To find the service container name for your subscription, in Visual Studio double click your service reference namespace in Solution Explorer. This opens Object Explorer. Select and expand your service reference namespace to reveal the series types and service container type for your subscription.


      For the InfoUSA service you are using for this project the container type name is InfoUSAHistoricalBusinessContainer, circled in red in the following screenshot.

      Object Explorer with Namespace Expanded
      
      class GetBusinessData
      {
          private Uri serviceUri;
          private InfoUSAHistoricalBusinessesContainer context;
      }
      
      
  3. Create a constructor for your GetBusinessData class.

    The constructor initializes the class’s private variables and creates credentials for the user.

    The serviceUri is the https link to your service which you copied to your clipboard in Step 2.2.c above. The context is the container for this service. It derives from DataServiceContext in the System.Data.Services.Client namespace and contains, among other things, your credentials.

    public GetBusinessData()
    {
       serviceUri = new Uri(SERVICE_URI);   // SERVICE_URI is the URL you copied to your clipboard in Step 2.2
       context = new InfoUSAHistoricalBusinessesContainer(serviceUri);
       context.Credentials = new NetworkCredential(USER_ID,             // Your Live Id
                                                   SECURE_ACCOUNT_KEY); // Your “Dallas” Account Key
    }
    
    
  4. Create a public method within your GetBusinessData class that returns a generic list. For our program the generic type is Nixie, though it could be any of the data series from this service (inside blue rectangles in the previous screenshot (Historical_Business, NewBusiness, or Nixie).

    This method queries the Nixie series. If the query is successful the resulting generic list is returned. If the query is unsuccessful for any reason an error message is displayed and null is returned.

    
    public IList<Nixie> getData()
    {
         IEnumerable<Nixie> query;
                
         query = from c in context.Nixie
                    select c;
         try
         {
             return query.ToList();
         }
         catch (Exception e)
         {
             Console.WriteLine("ERROR: {0} ", e.Message);
             return null;             // Return null if an exception is thrown
         }
    }
    
    
    The query can be any LINQ query and may optionally include the where filter and/or orderby. For more information on LINQ queries see LINQ Query Expressions (C# Programming Guide).

    The following query filters for CompanyName and State, then sorts the results in ascending order by ZipCode.

    
    query = from c in context.Nixie
                   where c.CompanyName != "" && c.State == "DE"  // no empty company names and from Delaware only
                   orderby c.ZipCode Ascending
                   select c;
    
    
  5. Write the code in Main() that will utilize your GetBusinessData class to obtain the data and then display the results.

    static void Main(string[] args)
    {
        GetBusinessData busData = new GetBusinessData();    // create an instance of your class
        IList<Nixie> dataList = busData.getData();          // populate your generic list with your query results 
    
        if (dataList != null)  // getData returns null if an exception is thrown.
        {
            // Display column headers
            Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "City", 
                                                               "Zip Code", 
                                                               "Business Name", 
                                                               "Phone");
    
            Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "--------------------", 
                                                               "----- ----", 
                                                               "------------------------------", 
                                                               "----------");
    
            // For each item in the list display selected fields
            foreach (Nixie d in dataList)
                Console.WriteLine("{0,-20} {1,5}{2,5} {3,-30} {4,10}", d.City, 
                                                                        // pad left with 0 for zips < 10000
                                                                        d.ZipCode.ToString().PadLeft(5, '0'),
                                                                        // if Zip4 is unknown print nothing
                                                                        // else pad left with 0’s for Zip4 < 1000
                                                                        d.Zip4 == null ? null 
                                                                                       : "-" + Zip4.ToString().PadLeft(4,'0'), 
                                                                        d.CompanyName, 
                                                                        d.Phone);
    
        }
        // No action in Main() if query failed.  The exception is handled in getData()
        // Pause until the user taps a key
        Console.Write("Tap any key to exit program. ");
        Console.ReadKey();
    }
    
    
    In Visual Basic there is no equivalent to the C# expression booleaExpression ? returnValueIfTrue : returnValueIfFalse so you need to create the following function to handle the Zip4 field neatly.

    
    Function GetZip4(ByVal Zip4) As String
        If Zip4 Is Nothing Then
            GetZip4 = "     " ' if no Zip+4 return 5 spaces
        Else
            GetZip4 = "-" + Zip4.ToString.PadLeft(4, "0"c) ' return "-" plus Zip+4 padded left with "0" for values < 1000
        End If
    End Function
    
    

The Completed Program

The following C# code is the completed program.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;                            // needed for authentication
using InfoUSABusinessData.InfoUSABusinesses; // RESTful proxy to data

namespace InfoUSABusinessData
{
    //-------------------------------------------------
    class Program
    {
        static void Main(string[] args)
        {
            IList<Nixie> dataList;        // Nixie is a series in InfoUSABusinesses namespace (see Object Browser for others)
            GetBusinessData busData = new GetBusinessData();    
            dataList = busData.getData();

            if (dataList != null)  // getData returns null if an exception is thrown.
            {
                // Display column headers
                Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "City", 
                                                                   "Zip Code", 
                                                                   "Business Name", 
                                                                   "Phone");
                Console.WriteLine("{0,-20} {1,10} {2,-30} {3,10}", "--------------------", 
                                                                   "----- ----", 
                                                                   "------------------------------", 
                                                                   "----------");

                // For each item in the list display selected fields
                foreach (Nixie d in dataList)
                    Console.WriteLine("{0,-20} {1,5}{2,5} {3,-30} {4,10}", d.City, 
                                                                            // ZipCode < 10000 pad left with 0s to keep five digits
                                                                            d.ZipCode.ToString().PadLeft(5, '0'),
                                                                            // Zip4 is unknown print nothing
                                                                            // Zip4 < 1000 pad left with 0s to keep four digits
                                                                            d.Zip4 == null ? null 
                                                                                           : "-" + d.Zip4.ToString().PadLeft(4,'0'), 
                                                                            d.CompanyName, 
                                                                            d.Phone);
            }
            // No action in Main() if query failed.  The exception is handled in getData()
            // Pause until the user taps a key
            Console.Write("Tap any key to exit program. ");
            Console.ReadKey();
        }
    }

    //-------------------------------------------------
    class GetBusinessData
    {
        // These constants should be used for this demo only
        // In a production environment you would write code for the user to input their id values OR
        //   to retrieve it from a database.
        // The account key should be encrypted to keep it secure. Do not pass the encrypted key to Dallas.
        //    USER_ID is your Live Id, and
        //    SECURE_ACCOUNT_KEY is your account key (found at the Marketplace under the Account keys tab)
        private const string USER_ID = "<your Live Id>";
        private const string SECURE_ACCOUNT_KEY = "<your Dallas Account Key>";
        private const string SERVICE_URI = "<the URL you pasted to your clipboard in Step 2.2>";

        private InfoUSAHistoricalBusinessesContainer context;   // see InfoUSABusinesses in Object Explorer for container name
        private Uri serviceUri;
      
        public GetBusinessData()
        {
            serviceUri = new Uri(SERVICE_URI);
            context = new InfoUSAHistoricalBusinessesContainer(serviceUri);
            context.Credentials = new NetworkCredential(USER_ID, SECURE_ACCOUNT_KEY);  
        }

        public IList<Nixie> getData()
        {
            IEnumerable<Nixie> query;
            
            query = from c in context.Nixie
                      where c.CompanyName != "" && c.State == "DE"  // no empty company names and from Delaware only
                      orderby c.ZipCode Ascending
                      select c;
            try
            {
                return query.ToList();
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: {0} ", e.Message);
                return null;             // Return null if an exception is thrown
            }
        }
    }
}


Had this been an ASP.NET web page instead of a Console Application, the results could have easily been bound to a DataGrid using the following code in place of the foreach loop above:

myDataGridView.DataSource = dataList;
Show:
© 2014 Microsoft