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-
Step 2 – A dialog pops up asking where the custom control is. Click “Add Reference”.
Step 3 – Click the “Browse” button and find the .dll for the custom Silverlight control that you made in the beginning. Hit OK.
Step 4 – Expand the reference that was added to select the actual custom control name. Hit OK.
Step 5 – You can modify the control’s properties to give it a name like “OData Service:” as I did below:
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.
And viola! A new browser window opens up with your OData service.
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
- public ODataFinder()
- {
- InitializeComponent();
- try
- {
- IModuleDefinition module = ClientApplicationProvider.Current.Details.GetModules().Where(i => i.Name.Contains("LightSwitchCommonModule")).First();
- // EntityContainer objects will be things such as ApplicationData, NorthwindData,...
- foreach (LightSwitch.EntityContainer globalItem in module.GlobalItems.OfType<LightSwitch.EntityContainer>())
- {
- ServicesDropDownList.Items.Add(globalItem.Name);
- }
- }
- catch (Exception)
- {
- // if we fail then we just won't populate any data sources
- }
- }
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
- private void ServicesDropDownList_DropDownClosed(object sender, EventArgs e)
- {
- try
- {
- string absoluteUri = Application.Current.Host.Source.AbsoluteUri;
- System.UriBuilder appUri = new UriBuilder(absoluteUri);
- string host = Application.Current.Host.Source.Host;
- int indexOfHost = absoluteUri.IndexOf(host);
- int indexOfEndOfHost = absoluteUri.IndexOf("/", indexOfHost + host.Length);
- string dataServiceUri = absoluteUri.Substring(0, indexOfEndOfHost);
- if (host.Contains("localhost"))
- {
- dataServiceUri = dataServiceUri + "/" + ServicesDropDownList.SelectedItem.ToString() + ".svc" + "/";
- }
- else
- {
- //Example format: https://IISMachine/AppName/Web/Application18.Client.xap?v=1.0.2.0?v=1.0.2.0
- int indexOfEndOfAppName = absoluteUri.IndexOf("/", indexOfEndOfHost + 2);
- int lengthOfAppName = indexOfEndOfAppName - indexOfEndOfHost;
- string appName = absoluteUri.Substring(indexOfEndOfHost, lengthOfAppName);
- dataServiceUri = dataServiceUri + appName + "/" + ServicesDropDownList.SelectedItem.ToString() + ".svc" + "/";
- }
- // Check to see if we are running in the Desktop
- if (AutomationFactory.IsAvailable)
- {
- var shell = AutomationFactory.CreateObject("Shell.Application");
- shell.ShellExecute(dataServiceUri);
- }
- // Else we are running in a web client
- else
- {
- //Open up the OData service in a new web page
- System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(dataServiceUri), "_blank");
- }
- }
- catch (Exception)
- {
- // if we fail then just don't display anything
- }
- }
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
Comments
Anonymous
July 12, 2012
Thanks Matt, Another gem. Thanks also for posting it in the Gallery, KeithAnonymous
July 12, 2012
Hi Matt, I'd like to echo Keith's comments. Brilliant article, which I'm sure will come in handy for a bunch of people. I'm not using LS 2012 RC yet, but things like this make me wish that I were. YannAnonymous
July 12, 2012
@Keith + @Yann - Thanks guys :) Happy that it's appreciated.