No Database, No Problem: Remote Data Services With .NET

I am a football (or if you’re American, soccer) fan. Recently, I got access to some data for the current season of the Premier League (2013/14), including things like fixtures (date, result, goals, shots, cards etc) and players (minutes played, goals, assists, cards and more). I decided to take advantage of this in order to create an application to analyze the stats to look for cool facts (like some of the things that commentators say on the TV).

Initially, I wanted to create a WPF application that I could share with other people, with the data stored centrally. However, the data should be stored in a format that would allow me to easily access it from a mobile app in the future.

This is where Telerik Platform comes in handy. I can store the stats in the Telerik Backend and they’ll be easily accessible via the .Net SDK from anywhere in the planet (as long there is Internet access). And when I am ready to create my mobile app, I can use AppBuilder to create it while utilizing the same data.

In this article, I’ll walk through getting started building this application by looking at how to set up the Telerik Backend Services, establish my data types, import my existing data and, finally, how to get that data back out within my WPF application.

Data

Before we start working with the Telerik Backend Services, let’s review the data that we’ll be working with. It contains two different types: players and teams.

Team

A team contains some basic information like the team name, city and stadium name, plus fixtures that provide in depth stats of each game played so far in the season. Here is a team in JSON format.

{ "Team" : { 
      "LongName" : "Newcastle United FC",
      "Name" : "Newcastle",
      "StadiumName" : "St. James' Park"
      "City" : "Newcastle",
      "TeamId" : "12",
      "Fixtures" : [ 
          { 
            "Date" : "2013-08-19T00:00:00.000Z",
            "Location" : "A",
            "OppositionStats" : { 
                "Fouls" : "9",
                "Goals" : "4",
                "GoalsHalfTime" : "2",
                "RedCards" : "0",
                "Shots" : "20",
                "ShotsMissed" : "9",
                "ShotsOnTarget" : "11",
                "Team" : "Man City",
                "YellowCards" : "2"
              },
            "Outcome" : "L",
            "OutcomeHalfTime" : "L",
            "Points" : "0",
            "Result" : "0:4",
            "TeamStats" : { 
                "Fouls" : "7",
                "Goals" : "0",
                "GoalsHalfTime" : "0",
                "RedCards" : "1",
                "Shots" : "20",
                "ShotsMissed" : "19",
                "ShotsOnTarget" : "1",
                "Team" : "Newcastle",
                "YellowCards" : "3"
              }
          }
        ],
    }
 }

Player

A player contains personal details such as their name, position and team, as well as stats from the games that he has played (or not) so far in the season. Below is a player, also in JSON format.

{ "Player" : { 
  "FirstName" : "Wojciech",
  "LastName" : "Szczesny",
  "Position" : "Goalkeeper",
  "TeamId" : "1",
  "TeamName" : "Arsenal"
  "GamesStats" : [ { 
        "Assists" : "0",
        "CleanSheets" : "0",
        "Date" : "2013-08-17T15:00:00.000Z",
        "GameOutcome" : "L",
        "GoalsConceded" : "3",
        "GoalsScored" : "0",
        "Location" : "H",
        "MinutesPlayed" : "90",
        "Opponent" : "AVL(H) 1-3",
        "OwnGoals" : "0",
        "PenaltiesMissed" : "0",
        "PenaltiesSaved" : "1",
        "Played" : "true",
        "RedCards" : "0",
        "Round" : "1",
        "Saves" : "3",
        "YellowCards" : "1"
      } ],
} }

Getting Set Up on the Telerik Platform

The first thing we need to get started is to create a Backend Services Project on the Telerik Platform. You can create a Backend Services Project following the steps from here.

Once the backend project is created we need to add new types. In order to do that, open the backend project, go to types and press “Create a Content Type.”

backend_appbuilder_1

Creating data types in the backend

By default every type contains the following fields: Id, CreatedAt, ModifiedAt, CreatedBy, ModifiedBy and Owner; these fields cannot be changed or removed.

Let’s start by mapping the fields for our two data types. For the Team type let’s create:

  • LongName, Name, Stadium and City of type Text.
  • TeamId of type Number.
  • Fixtures of type Object

When thinking about it, the Fixtures field probably seemed tricky, as it is a collection of complex type items containing strings, numbers and dates. However, the Object type can handle complex types very well.

The screenshots below show the mapping for the Team and Player data types. If you are following along, feel free to copy the types for Player from those listed in the image.

backend_appbuilder_2

backend_appbuilder_3

Once that is done we are ready to set up our Visual Studio project.

Preparing the Visual Studio project

The first step is to download Telerik Backend Services SDK. The SDK can be found at: https://platform.telerik.com/#downloads/backendservices. The download contains Newtonsoft.Json and the Telerik.Everlive.Sdk libraries and their configuration files.

Next create a Visual Studio project and import the backend services libraries to the project.

backend_appbuilder_4

Creating equivalent types in C#

In order to use the data types previously defined in the backend we need to create a class for each type. The task is rather straightforward – just follow these steps and you should be fine:

  • Create a new class and give it the same name as the type in the backend service;
  • Include: Telerik.Everlive.Sdk.Core.Model.Base;
  • Make it inherit from DataItem;
  • For every field create a public property with a public getter and a public setter;
  • Make sure to create a default parameter less constructor, or have no constructor at all;
  • For object type fields provide a class or a collection of a matching class;

For example, here is what my completed Player class looks:

using System;
using System.Collections.Generic;
using Telerik.Everlive.Sdk.Core.Model.Base;

public class Player : DataItem
{
    public int TeamId { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public String TeamName { get; set; }
    public String Position { get; set; }
    public List GamesStats { get; set; }
}

Below is the subclass for PlayerGameStats:

public class PlayerGameStats
{
    public DateTime Date { get; set; }
    public int Round { get; set; }
    public String Opponent { get; set; }
    public int MinutesPlayed { get; set; }
    public int GoalsScored { get; set; }
    public int Assists { get; set; }
    public int CleanSheets { get; set; }
    public int GoalsConceded { get; set; }
    public int OwnGoals { get; set; }
    public int PenaltiesSaved { get; set; }
    public int PenaltiesMissed { get; set; }
    public int YellowCards { get; set; }
    public int RedCards { get; set; }
    public int Saves { get; set; }
    public bool Played { get; set; }
    public String Location { get; set; }
    public String GameOutcome { get; set; }
}

Helpful tools

You might be pleased to hear that there are tools that can help generate the classes for you. This means that if your data is in the form of JSON, then your classes can be ready in a matter of moments.

The Backend Service in Action

Before we can perform any operations on the data, we will need to get the API Key from our backend services project.

Open the project and go to the API Keys section. Your API Key will be waiting for you in there. Copy the code as we’ll need to place it within our code.

Please bear in mind that you should never publish your API keys as this would allow unauthorized access to your data.

backend_appbuilder_5

Sending the data into Backend

Writing data to the data service takes just a few steps:

  • Create the data objects;
  • Prepare a backend service project link;
  • Create a facade for working with the required data store;
  • Export the data.

Below is the code to export a player object to the backend service. As you can see, while I had a good game for “Team Telerik,” the Grumpy Squirrels got trashed 3:0!

private void ExportData()
{
    //Prepare backend service project link
    var backend = new EverliveApp("ABC123apiKey");

    //Create facade to the required data store – note 
    var playerFacade = backend.WorkWith().Data();

    //Create data object
    Player player = new Player()
    {
        FirstName = "Sebastian",
        LastName = "Witalec",
        Position = "Midfielder",
        TeamName = "Team Telerik",
        TeamId = 1,
        GamesStats = new List()
        {
            new PlayerGameStats()
            {
                Assists = 1,
                GoalsScored = 2,
                MinutesPlayed = 90,
                Date = new DateTime(2013, 02, 19),
                Played = true,
                Opponent = "Grumpy Squirrels"
            }
        }
    };

    //Export the player record
    playerFacade.Create(player).ExecuteSync();
}

One you run this, you can view the new record in the Telerik Platform:

backend_appbuilder_6a

backend_appbuilder_6

As you can see by this example, it takes more time to create a player object than to actually send it to the backend service. In order to export data in bulk, just put all objects into an IEnumerable container and pass it into Create as a parameter.

InvalidTimeZoneException Exception

You may encounter an InvalidTimeZoneException exception that looks like:

backend_appbuilder_7

This means that one of the provided dates doesn’t have a DateTimeKind. In order to fix this you update the date by calling DateTime.SpecifyKind.

DateTime date = new DateTime(2013, 02, 19);
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);

Getting Data Back from the Backend

Now that we have some data, let’s read the data back from the backend service.

The first 2 steps of the process are the same as in the export process:

  • Prepare backend service project link
  • Create facade for working with required data store

After you complete these steps, you can to call GetAll to get all object or GetById to get a specific object.

Below is an example showing how to read back the record we created earlier. If you are following along, note that the ID for your player within the backend service will be different, so adjust the Guid value accordingly.

private void ReadData()
{
    //Prepare backend service project link
    var backend = new EverliveApp("ABC123apiKey");

    //Create facade to the required data store – note 
    var playerFacade = backend.WorkWith().Data();

    Guid id = new Guid("c84a13a0-9a3c-11e3-b6ca-d1980d6f4f32");
    var player = playerFacade.GetById(id).ExecuteSync();

    Console.WriteLine(player.FirstName + " " + player.LastName);
}

Final Thoughts

The best part of working with Telerik Backend Services is that there is no need to build any parsers or mapping logic. This is definitely much easier than using an XML-based data storage, SQL database or .Net object serialization, all of which require you to build both the read and the write logic, the handling for nulls and many other issues. With the Telerik Backend Services SDK, a correctly defined class is enough to transform the data from the backend service into a .Net object and vice versa.

Comments