I had a lot of questions in the last few days about the final demo on my Microsoft Sinergija session – the demo where the SharePoint list data have been displayed in a Windows 8 Metro Style client. Most of those questions were about people asking me to post the code for that client. But the main point is not the client-side code, it’s the way there.
So, no, I will not simply post the metro client code here, I will explain the way how to create such a client, how to get the necessary data - with the code snippets included, of course.
f you still haven’t read my posts from the SharePoint architecture series, then please read it, at least the “SharePoint Architecture – what are we talking about here?” post, since this post will heavily rely on it. Hence, this would not be possible without it at all.
First thing that you will need of course is Windows 8 Developer Preview, which can be downloaded here. And the full Visual Studio 2011 Developer Preview (not the Express edition which comes with Windows 8), which can be downloaded here. I will not go into the Windows 8 installation – like a thousand blogs have been written on that topic, so just find one of them.
So, we need to display, and eventually to write back, the SharePoint list data in a Windows 8 – Metro style client. Yes, the one with the tiles.
Since Metro clients are somewhat different – if developed in C# or VB, they rely on .NET 4.5, and have specific user programming model (WinRT) which “interfaces” between platform and programming language you are using (C# in this example), there is no way to access the SharePoint data directly, through the SharePoint Client Object model. Server Object Model is anyway out of reach.
It leaves us with only one possibility: we need to consume our data through services.
Since there is a known bug in the current version of the .NET framework 4.5, which doesn’t allow us to add a service reference for any OData service, it means that SharePoint OData services (listdata.svc) are not an option, too. And since we do not want to use SharePoint’s .asmx services (do I still need to explain why?), one remaining choice which we have, is to write an own WCF service, which will read the SharePoint data, and transport them back to the client.
This approach has another advantage: if we made the architecture of our solution properly, we probably already have API methods which read the data from SharePoint lists, we just need to leverage that functionality and to encapsulate it in a WCF service call.
If you recall the SharePoint Solution architecture schema I have proposed in the “What are we talking about here?” article, this would be the information flow in this case:
(click for larger image)
Pay attention on the boxes with the red borders: this is how the SharePoint data will reach our Metro client. Business Logic will read the data from SharePoint, by using the Data Access Layer Methods, and then a WCF Service will expose the calls to the appropriate Business Logic methods to the outer world.
We will use existing solution, which we have been working at in the last few articles, which deals with the Conference Organization.
We have in our “Sessions” SharePoint list agenda for the conference that we are organizing, and we want to expose that agenda to the different clients, among them the Windows 8.
We have also implemented a method in the business logic, which reads the agenda for a day, and this is what we are going to expose.
The WCF Service
Since SharePoint is “special”, we need to impose some boundaries on the WCF service that we will create for reading SharePoint data.
1. To keep the service separated from the SharePoint web applications, we will create a new site in IIS to host the web service – it will not be hosted inside the SharePoint site. But, we must use the existing SharePoint application pool, otherwise there will be no way to retrieve the SharePoint context.
2. We need to enable the Windows Authentication on the IIS site which hosts the service
3. The service needs to be build with .NET 3.5 (yeah, I know…)
4. ABC – service needs to use the BasicHttpBinding, to use the “TransportCredentialOnly” and “Ntlm” as security mode. We will need to use Ntlm authentication in our scenario, since considering other scenarios (Forms, Windows Live) would go way out of boundaries of this article.
Furthermore, we need to set the ASP.NET compatibility mode in the service as following:
<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” />
Whole ServiceModel of the web.config is shown here:
With this up and running, the service is able to accept the credentials from the clients, and to establish the SPContext under these credentials.
Now we need to call the methods from the business layer, to retrieve the data:
And that would be more the less all what is important on the service side. No business logic goes there – we have implemented that already in out business logic layer.
The Client – Windows 8 Metro style
I will not explain here Metro-style applications development, nor the new await/async methods in C# 5.0 There is more than enough information on that on the web. But I will use it to to call our service.
One thing is of importance here: Windows 8 machine is, in my case, member of the same domain as the SharePoint server. That allows me to authenticate with the default credentials. SharePont just needs to know who is knocking on it’s door, and what is he allowed to see.
If this is not possible, you will need to provide the username and password of a domain user when instantiating a client proxy, and then to authenticate with that user. A kind of a “proxy user”, which has necessary rights.
If this is not possible as well, then you have two options – turn the anonymous authentication on, or, implement the form based authentication with Windows Live – but that would go way behind the scope of this article. So, I will just suppose that the Windows 8 client and SharePoint server are in the same domain.
Create a new “Split application” from Visual C# / Windows Metro Style templates. Split application is good, because it shows the grouped data in a really nice manner, and we don’t have to do the layout for this example ourselves.
Set application capabilities
The next step is to add the “capabilities” to the newly created application – basically, permissions which our application will have. They can be found in the “Package.appxmanifest” file. The important one here is “Home/work Networking”, so we can talk to our service:
Add service reference
The next step is to add the reference to the service:
As you see, there is no App.config or Web.config to configure the service in the application. All the configuration is done in the proxy class, created for you when you add the service reference. Usually it is good enough, but I did encounter that the binding and security mode have not been “imported” properly. You can do it manually in the “reference.cs” file which is created under the service node (turn display all files on), but be aware: if you update the service reference, all of your changes to the reference.cs will be lost:
But, as I have said, this happens really rarely, so in 99% of the cases you can leave the Reference.cs alone.
Bind the data
After the service has been added, we will not do much more than change the Sample Data class in the template, and to put our SharePoint data instead of the hard-coded values which come with the template.
In the code below, I just retrieve the data from the service, iterate through it to create “Collections” and “Items” (elements in the “Split application”).
You notice, that, even if we do make an asynchronous call, we actually work as if it would be a standard synchronous call. This is made possible by the new C# 5 features (async/await), which were used in the service proxy class (again, take a look at the Reference.cs under the service node).
The binding is not done here, it ls in the App.xaml, if you are looking for it.
And that’s actually it. If you start the application, you will see your Conference Agenda, pulled right out of the SharePoint List, and displayed in the nice metro interface, grouped by the tracks (DEV, ADM, BUS).
Here are some screenshots:
Some further reading, stuff which has been used here: