While there is much work yet to be done on Conference Buddy on the client side, it isn’t too early to start thinking about how we’ll store data on a server. One option that might be ideal would be to use ASP.NET Web API.
ASP.NET Web API is a framework for building HTTP services. ASP.NET Web API has been designed to work well with RESTful (where REST is an acronym for REpresentational State Transfer) design principles.
Fortunately, ASP.NET Web API guides you into creating services that follow a RESTful style. We will follow that style as long as it is useful. To see this at work, create a new application, and in the templates select ASP.NET MVC4 from the templates
After entering the name ContactManager, click OK. In the next dialog select the Web API Template.
ASP.NET MVC takes great advantage of “convention over configuration” meaning that if you place files in the expected folders, and use the expected naming conventions, a great deal of work is done for you.
The first step is to create our Contact class. For this example, we’ll simplify Conference Buddy and build a simple contact manager, and the Contact class will be the fundamental data that we’ll use on both the server and the client.
Right click on the Models folder that was created for you and add a Contact.cs class
The first data annotation, ScaffoldColumn, indicates that the ContactId is controlled by the application and should not be set externally. The Required attribute indicates that, at a minimum, a Contact must have a name.
We are ready to create a Controller, but to do so we must first Build the application so that the Contact Model class will be available.
After building, right-click on the Controllers folder and select Add / Controller. Set the name of the controller to ContactsController.
Drop down the Template list and select
API controller with read/write actions, using Entity Framework.
Drop down the Model class list. If it is empty, you neglected to build the application, so cancel this dialog and build. From the drop down, select Contact (ContactManager.Models).
Drop down the Data context class list and select New Data Context. Name the new context
ASP.NET Web API (like ASP.NET MVC) uses conventions to simplify code while conforming to HTTP standards. As you can see, all of the controller action methods are named using HTTP verbs, and ASP.NET Web API will automatically route HTTP requests to the appropriate method based on name. Thus an HTTP GET request to /api/contacts will automatically route to the ContactsController's GetContacts method, simply by following naming conventions.
At this point, and with no further work, we have a functioning web service that uses Entity Framework to handle data persistence! Because this approach uses Entity Framework Code-First, it will automatically create our database – complete with tables based on our classes – when the service is first accessed.
Entity Framework also provides a method for inserting sample or initial data into our database when it's created, known as a database initializer.
Right click on the Models folder and create a new class named ContactManagerDatabaseInitializer.
This class has one purpose – provide data when the database is initialized. Here's the code for that class:
The ContactManagerContext was created for you and is used when overriding the Seed method (as we do above). When you register the initializer (see below) the initializer will be called by Entity Framework when it creates the database, and it will call your overridden seed method.
The context Contacts collection that you are adding to above is of type DbSet<Contact> which was created for you when you selected to create a new Data Context
We need to register this database initializer in Global.asax.cs. We do so in the Application_Start method
You now have a server ready to provide data to a Windows 8 client.
Right click on the solution and choose Add New Project. Select Windows Store in the left column, and Grid App in the right column. Name your application ContactManager.WindowsStore (once this technique is fully understood we’ll use Conference Buddy as the client side application).
We’ll need the WebApi client package to work with the WebAPI application we’ve built. Fortunately, this can be installed through NuGet. To do this, select View->Other Windows ->Package Manager Console. This window will open at the bottom of your screen. At the Package Manager prompt (PM>) enter the following command:
Hit Enter and the package will be installed,
We need to share the Contact class in the Server class as well as in the client. Copy and paste the class into the client project (yuck, but simpler for this example).
Right click on the DataModel folder and create a new class named Contact. Paste in the Contact class from ContactManager, eliminating the attributes,
Within the ContactManager.WindowsStore project, open the SampleDataSource.cs file in the DataModel folder. Add the following functions to the end of the SampleDataSource class:
Take a close look at the first function, LoadDataAsync:
This function will be calling into our service. In the current example application, this will need to match the port number used by the ASP.NET Web API application. To find this, scroll up to the ContactManager project and double click on the Properties
When the Properties display opens, click on Web (in the left column) to open the Web tab. About half way down the page you’ll find the Servers section. Within that, find the Project Url for the Local IIS Web Server and note the Port Number.
Change the port number in your code accordingly,
If the Boolean value clear evaluates to true, we clear the data source before fetching data from the web service. In this case, we do want to have sample data available for design-time support, but we don't want to have the sample data flash on the screen when the application runs, so we'll leave the default to true.
We then instantiate an HttpClient object and set its BaseAddress. We use that to get the contacts asynchronously. They are returned as JSON data that we can then read into a collection of Contact objects.
Surprisingly, this is all you need to do to call a webservice which returns JSON data. The HttpClient object will make the request, wait asynchronously for the response, and deserialize the result to an array of Contact objects.
The SampleDataSource can hold separate groups of data. We're returning all contacts in an AllGroups grouping, but we could split these up if we had a meaningful way to do that – by geographical region, for instance. We'd add those groups to the _sampleDataSource.
Notice that the third parameter in the SampleDataItem constructor is GetContactInfo which takes the contact as a parameter. This returns a string based on what information is available for the Contact,
This is the data that will be displayed on the Group and on the Items page. That data is displayed automatically as we’ve passed that string in as the third parameter to the SampleDataItem, and that third parameter is the Sub-title.
Key to understanding how this works is that we are not changing any of the out of the box behavior of the Grid App template; we are simply providing alternative data to the built-in sample data, mapping our contact data to the expected strings.
We're using another web service for our avatars, avatars.io. This site takes a handle and tries to find the best avatar image from popular social networking sites like Twitter and Facebook.
Finally, we'll need to call the LoadDataAsync method from App.xaml.cs. Add the line
above the call to Window.Current.Content.RootFrame,
Run the application and the Grid App page is displayed using the default display characteristics, but using our data from our Web Service, rather than the sample data.
Download the Source Code for this demonstration
Jesse Liberty has three decades of experience writing and delivering software projects. He is the author of 2 dozen books and has been a Distinguished Software Engineer for AT&T and a VP for Information Services for Citibank and a Software Architect for PBS. You can read more on his personal blog or follow him on twitter
Subscribe to be the first to get our expert-written articles and tutorials for developers!