A Brief Look at .NET Backends for Azure Mobile Services – Part 2

In the last article we looked at the basics of the new support for .NET in Azure Mobile Services.  This included creating a trivial controller that handle some basic math; obviously this was done to communicate concept as this sort of controller would have little value in most applications.

Quick Note: As this is looking at a Preview feature of Azure some of what may be here could be outdated.  I wrote this article on 3/16/2014, so bare that in mind.

Problems with the TodoItem Example

When you create a new Mobile Service you are always given a Quickstart Todo item application to help get you started.  This is usually quite helpful, however, it can lead to great confusion with the .NET backends, especially if you are just playing around.

Before we get into that, a good tip to help with tracking down errors is to increase the error handling; it would seem set fairly low by default.  To do this bring up your WebApiConfig file (under App_Start) and update Register to set the ConfigOptions MinimumTraceLevel to Info.  This will do much to increase the information you receive in your Mobile Service logs.

In this same file, you will notice a class definition for an Initializer (the class will inherit from DropCreateDatabaseIfModelChanges).  This will be the source of your problems at first. This initiaization pattern was first developed in the early days of Code First Entity Framework, before Migrations became the preferred way.  It was designed for development environments where the persistence of the data is less important. It accomplishes this by dropping the entire database when a model change is detected.  While this is fine for a local database, no Mobile Service has permission to drop a database in SQL Azure.  This means if you publish and then publish again with a model change, your service will cease funcitoning.

I anticipate this is going to change in the future, but it caused me a huge headache during my early research with this; I eventually got to a point where I had to throw away the Mobile Service I had been using and start again.  The best way to solve this problem is to use Migrations, but even that has issues.

Problems Migrating

Assuming you are starting with a freshly created Mobile Service and you had downloaded the source code, the first thing you will want to do is run Enable-Migrations (I use the Library Package Manager console).  This will update the project and add in the Configuiration class which will, through convention, replace your original Initializer; that said need to at least comment out the SetInitializer call in the WebApiConfig static class (under App_Start).

Side note: I always advocate the data layer should be created in a separate project and separated from the web project.  Such an explanation is outside the scope of this article.

With Migrations enabled,  you will need to add the initial migration.  I generally do ‘Add-Migration “Initial Migration”’ or something to that effect, this is where the problems will come in.

If you run Update-Database the application of the Seed method will fail.  The reason for this is curious.  Microsoft requires that your objects which will be stored in SQL Azure have their class definitions inherit from EntityData which will provide the standard columns that all Mobile Services feature.

The problem is that, within the Seed method, the CreatedAt column is marked as a clustered index.  If you know anything from SQL Server it is that you are only permitted to have one clustered index per table.  I believe marking the Id field as a Primary Key (which the migration does) makes it a clustered index as well, thus giving you two.  You can easily get around this by removing the Index definition; not sure why this decision was made.

After you do this Update-Database should execute without error.

The server will operate it much the same way to perform the migrations.  However, as an added measure, inform the Publish Profile to run Code First migrations at app startup.

image

This will ensure the Code First migrations run.

Testing

To make testing things easier from this point forward, allow Anonymous access to the Get method of the TodoItemController (below).

        [RequiresAuthorization(AuthorizationLevel.Anonymous)]
        public IQueryable GetAllTodoItems()
        {
            return Query();
        }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

You should be able to run the Web project and either use IE, Fiddler or something similar to hit the following URL: http://localhost:#####/tables/TodoItem which will return a JSON file with a couple TodoItem entries inside. You can then run a simple Publish and push your contents to Mobile Services.  After completion, your default browser will open to the root page of your Mobile Service.  Simple append /tables/TodoItem and you should get the same results as before.  If you do not, check your Logs

Adding New Entities

If you have worked with Code First Entity Framework in the past much of this will be a review.  First create a class, we will call it Person.  Add three properties FirstName, LastName (string), and BirthDate (DateTime) – see below:

    public class Person : EntityData
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
    }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Notice that the entity inherits from EntityData.  This base class provides all of the necessary default fields all SQL Azure tables will have (at least those created through Mobile Services).

The next thing we need is a DbSet (or context).  The application comes with one of these already setup (assuming you are using the starter project).  For our purposes, we will add the People property to represent the appropriate table. See below

    public class peoplegreeterContext : DbContext
    {
        // Full file omitted for brevity

        private const string connectionStringName = "Name=MS_TableConnectionString";

        public peoplegreeterContext() : base(connectionStringName)
        {
        } 

        public DbSet TodoItems { get; set; }
        public DbSet People { get; set; }
    }.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

This will indicate to Entity Framework that People is a table that should exist in the database, the migrations will indicate that the table should be created when the Update-Database command is executed as part of the deployment process.

Because what you are working with here is effectively just a managed instance of WebAPI the same routing rules apply as you are used to from previous versions.  However, as part of Mobile Services you do get some convenience methods and classes as well.

Most of these are contained in the base class TableController where T is a class which inherits from EntityData.

More coming in the final part, part 3

Advertisements

One thought on “A Brief Look at .NET Backends for Azure Mobile Services – Part 2

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s