Finding Your LightSwitch Produced OData Services (Visual Studio 2012)

With the latest version of LightSwitch in Visual Studio 2012 you can now consume as well as produce OData services from the data sources managed by the LightSwitch middle-tier. But if we want to interact with the OData services that LightSwitch produces we need to know how to reference them directly.

We’re going to learn how to do this today with a custom Silverlight control for our LightSwitch applications to help us easily view the OData service that LightSwitch produces for each data source on our application.

(If you want some more detailed info on how LightSwitch makes and uses OData services, then John Rivard has a good article on just how LightSwitch uses OData services - LightSwitch Architecture: OData).

Where is my OData Service?

If I make a LightSwitch application with a couple of data sources, like NorthwindData and ApplicationData, and build then we will have two OData services that will be automatically created for us. These OData services will be named: NorthwindData.svc and ApplicationData.svc. This is the important bit - each data source gets its own OData service. The diagram below illustrates this well:

These OData services are used by the LightSwitch client to communicate with the LightSwitch server. But maybe you want to query these OData services directly yourself with your own OData client (like Power Pivot for example), or maybe you’re just curious what these services look like.

If you launch a published LightSwitch web application you will see the url look something like: https://MyServer/MyLightSwitchApplication/. And if you wanted to directly query the OData service for the Northwind data source directly you could just modify the url like so: https://MyServer/MyLightSwitchApplication/NorthwindData.svc/.

As you can see, the format for referencing the OData service is https:// + server name + application name + OData service name:

To know what the OData service name is however, you would need to know the data source names. You probably don’t have this knowledge unless you were the developer of the data model, and even then perhaps you’ve published your LightSwitch application several months ago and now you no longer recall the data source names.

Find it with a custom control

We can simplify finding the LightSwitch produced OData service by creating a custom Silverlight control, adding it to our screen, then clicking a button to launch our OData service.

Our custom Silverlight control will utilize the LightSwitch API to determine what the name of our OData service is, and then it will launch a new browser window with the OData service as the URL.

If you haven’t used custom controls before, it just takes a few steps to add it to your screen. 

1) Follow the basic steps over on my Code Gallery post, Custom Silverlight Control to find LightSwitch OData Services, to build the custom Silverlight Control into a .dll that we will use later

2) Create a LightSwitch Web application, add some data and add a screen (I created a table called “MyBook” to the ApplicationData data source) 

3) Add a screen

4) Add a custom control to the screen like so:

Step 1 – Select Add –> New Custom Control-

image

Step 2 – A dialog pops up asking where the custom control is. Click “Add Reference”.

image

Step 3 – Click the “Browse” button and find the .dll for the custom Silverlight control that you made in the beginning. Hit OK.

image

Step 4 – Expand the reference that was added to select the actual custom control name. Hit OK.

image

Step 5 – You can modify the control’s properties to give it a name like “OData Service:” as I did below:

image

Step 6 – F5 it! You’ll see the control at runtime on your screen. Click the drop down arrow to see a list of your OData services that are available to you.

image

And viola! A new browser window opens up with your OData service.

image

 

Quick look at the code

Let’s take a look at the Silverlight custom control code.

In the constructor code below, which is invoked when the control is created, we are doing a few things:

1) We are looking through the list of Modules available to the client. The one we want specifically is called LightSwitchCommonModule

2) We get all the EntityContainers off of the LightSwitchCommonModule and store them in a List object which we wil use later. An EntityContainer will be our data source (e.g. ApplicationData, NorthwindData, etc.)

3) The List object we populated with Data Source names is bound to the custom Silverlight control. That is the data the user will see at runtime available as a drop down list.

Control Constructor

  1. public ODataFinder()
  2.         {
  3.             InitializeComponent();
  4.  
  5.             try
  6.             {
  7.                 IModuleDefinition module = ClientApplicationProvider.Current.Details.GetModules().Where(i => i.Name.Contains("LightSwitchCommonModule")).First();
  8.  
  9.                 // EntityContainer objects will be things such as ApplicationData, NorthwindData,...
  10.                 foreach (LightSwitch.EntityContainer globalItem in module.GlobalItems.OfType<LightSwitch.EntityContainer>())
  11.                 {
  12.                     ServicesDropDownList.Items.Add(globalItem.Name);
  13.                 }
  14.             }
  15.  
  16.             catch (Exception)
  17.             {
  18.                 // if we fail then we just won't populate any data sources
  19.             }
  20.         }

 

Our custom control is a drop down list. When the drop down is closed we will try to launch the OData service URL in a browser.

This method below does that in the following way:

1) Get the URI of the Host machine, which will be something like “https://myServer/myApp/App.xap”

2) We parse off the name of the Host machine, and the name of the application

3) We combine the host name + the application name + the data source name selected by the user to form a URL. Something like https://myServer/myApp/ApplicationData.svc/.

4) We launch the URL in a web browser (the way we launch it in a web browser varies a bit on whether or not we are in a Desktop client or a Web client)

Control Closed Method

  1. private void ServicesDropDownList_DropDownClosed(object sender, EventArgs e)
  2.         {
  3.             try
  4.             {
  5.                 string absoluteUri = Application.Current.Host.Source.AbsoluteUri;
  6.                 System.UriBuilder appUri = new UriBuilder(absoluteUri);
  7.  
  8.                 string host = Application.Current.Host.Source.Host;
  9.                 int indexOfHost = absoluteUri.IndexOf(host);
  10.                 int indexOfEndOfHost = absoluteUri.IndexOf("/", indexOfHost + host.Length);
  11.                 string dataServiceUri = absoluteUri.Substring(0, indexOfEndOfHost);
  12.  
  13.                 if (host.Contains("localhost"))
  14.                 {
  15.                     dataServiceUri = dataServiceUri + "/" + ServicesDropDownList.SelectedItem.ToString() + ".svc" + "/";
  16.                 }
  17.                 else
  18.                 {
  19.                     //Example format: https://IISMachine/AppName/Web/Application18.Client.xap?v=1.0.2.0?v=1.0.2.0
  20.                     int indexOfEndOfAppName = absoluteUri.IndexOf("/", indexOfEndOfHost + 2);
  21.                     int lengthOfAppName = indexOfEndOfAppName - indexOfEndOfHost;
  22.                     string appName = absoluteUri.Substring(indexOfEndOfHost, lengthOfAppName);
  23.  
  24.                     dataServiceUri = dataServiceUri + appName + "/" + ServicesDropDownList.SelectedItem.ToString() + ".svc" + "/";
  25.                 }
  26.  
  27.  
  28.                 // Check to see if we are running in the Desktop
  29.                 if (AutomationFactory.IsAvailable)
  30.                 {
  31.                     var shell = AutomationFactory.CreateObject("Shell.Application");
  32.                     shell.ShellExecute(dataServiceUri);
  33.  
  34.                 }
  35.                 // Else we are running in a web client
  36.                 else
  37.                 {
  38.                     //Open up the OData service in a new web page
  39.                     System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(dataServiceUri), "_blank");
  40.                 }
  41.             }
  42.  
  43.             catch (Exception)
  44.             {
  45.                 // if we fail then just don't display anything
  46.             }
  47.         }

 

Bring it all together

We’ve covered a couple things here:

a) How you can go about manually finding your OData services that LightSwitch produces for each data source

b) How you can make this a bit easier by adding a custom Silverlight control your LightSwitch applications to find and display the OData service for you.

Check out my Ccode Gallery post, Custom Silverlight Control to find LightSwitch OData Services, for the code and for some more details on how to make this custom SL control.

Thanks all, and please let me know if you have any feedback.

-Matt Sampson Martini glass

Digg This