Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

Manually Using Fiddler to Authenticate

One thing I would encourage anyone planning to use Azure Active Directory to authenticate users is to understand a bit more about the oauth 2.0 workflow. To this end I’m going to follow the instructions on the blog post, Using Fiddler to acquire a JWT ( JSON Web Token ) for use with the Graph API, to access content from the Azure Mobile Service. I’d also suggest reading this page which covers the Authorization Code Grant Flow

Requiring Authentication on the Azure Mobile Service

In the previous post I configured a Azure Active Directory and the Mobile Service with the appropriate application definitions. This in itself isn’t enough – you can prove this by making a request using Fiddler to the existing controllers eg  GET https://realestateinspector.azure-mobile.net/tables/realestateproperty (don’t forget you’ll need to specify the X-ZUMO-APPLICATION header). Mobile Services already require the use of the X-ZUMO-APPLICATION key to be specified on requests, but what we want to do is enforce a user-level authentication.Luckily it’s as simple as adding the AuthorizationLevel attribute to the controllers with the level set to AuthorizationLevel.User. In the following code I’ve applied the attribute to the base controller I created earlier.

public class RealEstatePropertyController : RealEstateBaseTableController<RealEstateProperty> { }

public class InspectionController : RealEstateBaseTableController<Inspection> { }

[AuthorizeLevel(AuthorizationLevel.User)]
public class RealEstateBaseTableController<TEntity> : TableController<TEntity>
    where TEntity : class, ITableData
{

When I publish this update and attempt to run the same Fiddler request I get a 401 unauthorized exception:

HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 61
Content-Type: application/json; charset=utf-8
Expires: 0
Server: Microsoft-IIS/8.0
WWW-Authenticate: Basic realm="Service"
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=0289d9a2e779a2431db31b4a154e84828a77f89dbbe1fe391d5fe9794f54f970;Path=/;Domain=realestateinspector.azure-mobile.net
Date: Wed, 14 Jan 2015 11:14:21 GMT

{"message":"Authorization has been denied for this request."}

Adding Azure Active Directory Authentication to Azure Mobile Service

In my post “Add Azure Active Directory Support to Azure Mobile Services-Enabled Windows Phone Apps” I go through how to setup Azure Mobile Service to work with Azure Active Directory. Firstly I’m going to create a separate directory for this application. From the toolbar at the bottom of the Azure management portal I select App Service –> Active Directory –> Directory –> Custom Create

image 

The Name of the Azure Active Directory (AAD) is a friendly name which you can use to identify the directory in the portal. The Domain Name has to be unique and will be the identifier, and default tenant, of the directory.

image

The next thing I’ll need is to create two Application entries within the AAD. You can think of applications as the glue that connects AAD to both the Mobile Service (the resource being protected) and the native client applications.

I’ll first create an application that will link AAD to the Mobile Service. From the Applications pane in the AAD, click Create, followed by the link to “Add an application my organisation is developing”.

image

Next I need to give the application a name (again this is for identification in the portal – as you’ll see the name I chose is quite long and gets truncated in some of the later views, so I’d suggest a shorter name), and select “Web Application and/or Web API” under the Type heading.

image 

On the next pane I’m prompted to enter a App Id and Reply Url. On a separate pane I’ll open up the Mobile Service and go to the Identity pane. At the bottom under the Windows Azure Active Directory section I’ll copy out the App Url (ie https://realestateinspector.azure-mobile.net/login/aad). This value should be set for both App Id and Reply Url. After completing the creation process for the application, copy the Client Id value from the Configure pane and switch back to the Identity pane of the Mobile Service. Enter the Client Id into the Client Id field under the Windows Azure Active Directory section. I also need to specify the allowed tenant, which in this case is the default tenant from the AAD I created earlier.

image

Next I’ll create an application that will connect our native client applications to AAD. This time I’ll select Native Client Application under the Type heading.

image

On the next pane I’m prompted for a redirect url. For the timebeing I’m going to enter a placeholder value (eg http://tba.com)– we’ll come back to this when I start writing the code in the native applications to authenticate with AAD.

Now that I have applications that represent both the Mobile Service and the native client applications, I need to establish a trust relationship between them. From the Configure pane of the application for the native clients, select Add Application from the “permissions to other applications” section. Select Other in the Show dropbox and click the tick button to invoke the search. Select the application for the Mobile Service (ie in this case the Real Estate Inspector Mobile Service) and click the tick button at the bottom of the dialog.

image

From the Delegated Permissions dropdown, check the box next to “Access Real Estate Inspector Mobile Service” and click Save from the lower toolbar of the pane.

image

This completes the configuration of AAD to work with Mobile Service and Native Client applications. In the coming posts we’ll leverage this configuration to authenticate the mobile applications.

Building the Xamarin.Forms Basic Layout Using XAML

The initial content page that was created when we created the XForms projects was done in code. Rather than doing the layout in code, I prefer to work in XAML – not only does this make the design more declarative, it is also miles easier to data binding. I’ll start by creating a new Forms Xaml Page.

image

Next we’ll add some XAML to the page (similar to what we added to the Windows MainPage):

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="
http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="RealEstateInspector.XForms.MainPage">
  <ListView ItemsSource="{Binding Properties}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <ViewCell.View>
            <Label Text="{Binding Address}" />
          </ViewCell.View>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</ContentPage>

And in the code behind for the MainPAge we’ll create, assign and load data into the MainViewModel:

protected async override void OnAppearing()
{
    base.OnAppearing();

    var vm = new MainViewModel();
    BindingContext = vm;
    await vm.LoadPropertyData();
}

And of course I need to update the code in App.cs to use the new XAML MainPage, rather than the code created ContentPage:

public App()
{
    // The root page of your application
    MainPage =new MainPage();
}

When you go to run this you’re likely to see errors due to lack of references for the SQLite extensions. Most references will get added if they are used by referenced libraries. What makes SQLite different is that there are platform specific implementations which are only added to the platform specific project. As such you need to make sure all the client applications have the SQLiteStore NuGet package referenced. I ran into issues applying the NuGet package to the Android project as it seemed to not be able to find the HttpClient NuGet package – I had to add this NuGet package to the Android project first, before applying the SqliteStore NuGet Package.

image

After doing this I was able to run up the XForms applications on each of the platforms, each displaying the addresses of the properties in my local offline database.

Thinking About MVVM and View Models

At this point I’m rather postponing the inevitable need to add an MVVM framework into my application. I’m not going to delve into into what MVVM is as I think that’s a conversation for another day and there are existing sites/reference that more than do this topic justice. However, enough to say that there is an important role for MVVM in the mobile app development space, particularly with Windows platform and Xamarin.Forms where we can use data binding. The reason I’ve been putting it off is that in the past I would have gone the MVVMcross route but I’m yet to see this work against Xamarin.Forms. This leaves me with the need to evaluate other frameworks such as MvvmLite (a long term player in the MVVM space), ReactiveUI and Calcium. I’m still on the hunt for the next killer framework that I’ll use religiously, in the meantime I’m going to avoid the need to make a decision by starting by manually creating and assigning the viewmodel for the main page of the application.

To abstract our view models away from the specifics of how the data is going to be presented (ie the premise of MVVM) I’ll create a separate Portable Class Library which will contain my view models.

image

When setting the targets, don’t forget to include Windows Phone Silverlight 8, otherwise you won’t be able to use the PCL from the XForms project.

image

Into this library I’ll create a ViewModels folder and then my first view model, MainViewModel. I’ll then migrate the logic that I had in my shared code from my Windows platform applications across into this view model. This includes

- Adding NuGet package reference to the Microsoft.WindowsAzure.Mobile and Microsoft.WindowsAzure.Mobile.SQLiteStore (just add the latter as the former will be added automatically)

- Add reference to the shared entities project so that the view models can access the data entities

- Remove references to the shared entities projects from the Windows platform projects (otherwise you’ll end up with type reference errors since you’ll effectively have two copies of the entity classes).

- Move the MobileServiceClientExtensions class I created previously into the new portable class library

- Add reference to the new PCL to the XForms and Windows platform projects.

The final outcome is a view model which loads all the properties when the LoadPropertyData method is invoked

public class MainViewModel
{

    public static MobileServiceClient MobileService = new MobileServiceClient(
        "https://realestateinspector.azure-mobile.net/",
        "wpxaIplpeX-----------------------------g12"
        );

    private ObservableCollection<RealEstateProperty> properties = new ObservableCollection<RealEstateProperty>();

    public ObservableCollection<RealEstateProperty> Properties
    {
        get { return properties; }
    }

    public async Task LoadPropertyData()
    {
        var data = new MobileServiceSQLiteStore("inspections.db");
        data.DefineTable<RealEstateProperty>();
        data.DefineTable<Inspection>();

        await MobileService.SyncContext.InitializeAsync(data, new MobileServiceSyncHandler());

        await MobileService.PullLatestAsync<RealEstateProperty>();
        await MobileService.PullLatestAsync<Inspection>();

        var props = await MobileService.GetSyncTable<RealEstateProperty>().ToListAsync();
        foreach (var prop in props)
        {
            Properties.Add(prop);
        }
    }
}

Let’s return to our Windows platform applications and wire up a basic interface. In the MainPage.xaml for the Windows project I’ll add some basic layout – this is just to demonstrate that properties are being synchronised and loaded.

<Page
    x:Class="RealEstateInspector.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.Resources>
            <DataTemplate
                x:Key="PropertyItemTemplate">
                <TextBlock
                    Text="{Binding Address}"
                    FontSize="30"
                    Foreground="WhiteSmoke"/>
            </DataTemplate>
        </Grid.Resources>
        <ListView ItemTemplate="{StaticResource PropertyItemTemplate}"
                  ItemsSource="{Binding Properties}"/>
    </Grid>
</Page>

Adding Xamarin.Forms Support

So far I’ve only had support for the new Windows platform clients (ie Windows and Windows Phone) for my Real Estate Inspector sample app. However, to make it successful we need to target more platforms. To this end I’m going to add support for iOS, Android and Windows Phone 8.0 using Xamarin.Forms.

After installing the Xamarin tooling for Visual Studio, I added a new project using the Blank App (Xamrain.Forms Portable) template. This actually look multiple attempts as I hadn’t updated the Xamarin tooling prior to creating the projects. I would highly recommend upgrading the tooling first!

image

This will give you three target projects Driod, iOS and WinPhone, in addition to a PCL which contains the common code and ui for the applications. You should be able to build and run each of these targets – however, you’ll need to either register for a trial or have a Xamarin Business subscription. Since the UI is help in the PCL project, it’ll be the same across all the targets, although there may be platform rendering differences.

Now that we have these three targets, we’re going to have to connect up our Azure Mobile Service, work out how we’re going to deal with navigation and structure our solution to maximise code reuse across our Windows platform projects.

Improving the Differential Synchronisation using Azure Mobile Services

As a mobile developer one of the things I’m critical of is ensuring that network requests are kept to a minimum. Having built several sync solutions in the past I was a little surprised with the current Azure Mobile Service implementation, and here’s why. By now, if you’ve read my previous posts you’ll recall seeing that each table is synchronised by invoking PullAsync to retrieve the latest updates from the Mobile Service, and invoke PushAsync to push local changes up to the Mobile Services. This seems reasonable – however, what I saw when I ran Fiddler is that each time I synchronised a table I would always seem the most recent entry being returned. Not believing what I saw I repeatedly ran the PullAsync method, and sure enough, each time I invoked it, the most recent entity would be returned. This in itself wouldn’t be so bad but the way that the Mobile Service offline support works out if it has retrieved all the entities for a query is to add the $skip query string to each query until no items are returned. The upshot is that not only does the most recent entity get returned, a second unnecessary call is made which returns no items – so there’s a network bandwidth and latency cost!

The reason for this is that there is a difference in time resolution between Entity Framework and SQL Server. Let’s use Visual Studio, or SQL Server Management Studio, or the online Azure SQL management tool, to query the contents of the Inspections table. Here we can see that the most recent update to this table was at 2015-01-09 11:45:40.0194886 +00:00.

image

Now, let’s take a look at the queries that PullAsync generates – the query filter is updatedAt >= 2015-01-09 11:45:40.0190000 +00:00. Firstly, this uses ge which is greater than or equal. Secondly, look at the lack of precision in the timestamp – this means you’re always going to get the most recent entry returned (at least). You’ll see that the second query uses the same filter, except it adds $skip=1 to jump over the entry that was returned by the first query.

https://realestateinspector.azure-mobile.net/tables/Inspection?$filter=(__updatedAt%20ge%20datetimeoffset'2015-01-09T11%3A45%3A40.0190000%2B00%3A00')&$orderby=__updatedAt&$skip=0&$top=50&__includeDeleted=true&__systemproperties=__createdAt%2C__updatedAt%2C__version%2C__deleted
https://realestateinspector.azure-mobile.net/tables/Inspection?$filter=(__updatedAt%20ge%20datetimeoffset'2015-01-09T11%3A45%3A40.0190000%2B00%3A00')&$orderby=__updatedAt&$skip=1&$top=50&__includeDeleted=true&__systemproperties=__createdAt%2C__updatedAt%2C__version%2C__deleted

Now, let’s see if we can improve the query – we’re going to change this:

var inspectionQ = MobileService.GetSyncTable<Inspection>().CreateQuery();
await MobileService.GetSyncTable<Inspection>().PullAsync(typeof(Inspection).Name, inspectionQ);

To this:

await MobileService.PullLatestAsync<Inspection>();

Where PullLatestAsync is an extension method defined as follows:

public static class MobileServiceClientExtensions
{
    public async static Task PullLatestAsync<TTable>(this IMobileServiceClient client) where TTable : BaseEntityData
    {
        // Get the most recent
        var mostRecent = await client.GetLatestAsync<TTable>();

        // Convert the most recent into a query (assuming there is one)
        if (mostRecent != null)
        {
            var maxTimestamp = mostRecent.UpdatedAt.AddMilliseconds(1);
            var q = client.GetSyncTable<TTable>()
                .CreateQuery()
                .Where(x => (x.Id != mostRecent.Id || x.UpdatedAt > maxTimestamp));
            // Do a (filtered) pull from the remote tabl
            await client.GetSyncTable<TTable>().PullAsync(typeof(TTable).Name, q);
        }
        else
        {
            await client.GetSyncTable<TTable>().PullAsync(typeof(TTable).Name, client.GetSyncTable<TTable>().CreateQuery());
        }
    }

    public async static Task<TTable> GetLatestAsync<TTable>(this IMobileServiceClient client) where TTable : BaseEntityData
    {
        return (await client.GetSyncTable<TTable>()
                            .OrderByDescending(x => x.UpdatedAt)
                            .Take(1)
                            .ToListAsync()).SingleOrDefault();
    }
}

This extension method requires us to extend our BaseEntityData to include the UpdatedAt property so that we can use it in our query:

public class BaseEntityData
#if SERVICE
    : EntityData{}
#else
{
    public string Id { get; set; }

    [CreatedAt]
    public DateTimeOffset CreatedAt { get; set; }

    [UpdatedAt]
    public DateTimeOffset UpdatedAt { get; set; }

    [Version]
    public string Version { get; set; }

}
#endif

Running this now, we see that our filter expression has been extended to exclude the most recent entity, unless it has changed.
https://realestateinspector.azure-mobile.net/tables/Inspection?$filter=(((id%20ne%20'6d9f9a19-da8f-4bd6-a4d3-dd888a67e00e')%20or%20(__updatedAt%20gt%20datetimeoffset'2015-01-09T22%3A45%3A40.0200000%2B11%3A00'))%20and%20(__updatedAt%20ge%20datetimeoffset'2015-01-09T11%3A45%3A40.0190000%2B00%3A00'))&$orderby=__updatedAt&$skip=0&$top=50&__includeDeleted=true&__systemproperties=__createdAt%2C__updatedAt%2C__version%2C__deleted

Synchronizing Data for Offline Access with Azure Mobile Service

One of the core requirements of our real estate inspection tool is that it’s available offline. To this end I can leverage the synchronisation component of the Azure Mobile Service SDK to synchronise the entities we referenced in the previous post. In order to make use of this I will need to add another NuGet package which is the WindowsAzure.MobileService.SqliteStore package – you can think of this as the Sqlite storage wrapper which will handle persisting and providing an access layer to the offline data.

image

One thing you may notice that that there is a warning in your References list after adding this NuGet package. In this case you either haven’t got the Windows/Windows Phone Sqlite Extensions installed, or your version doesn’t align with the reference that was added as part of adding the previous package. After making sure you have the most recent version of the Sqlite extensions installed (get them from the Sqlite Download Page), you can then simply delete the reference with the warning, and then add a new reference to the extensions you just installed.

image

Next, you’ll probably still see warnings against the Sqlite and Visual C++ references – this is because neither of these references supports compiling using the AnyCPU option. Switch to building for one of the other platforms (x86 is probably the easiest to use for development since it’s compatible with the Windows Phone emulator, just don’t forget that if you’re testing  on an RT device or on a real Windows Phone, you’ll need to use an ARM build).

image

Now we have our references, let’s add some code to demonstrate synchronising, reading and writing from the offline data store. I already have my MobileService that I setup in a previous post but I’m going to replace my the method call to GetTable<>.ToListAsync() with code that will synchronise data for offline access. I’ll start by defining the offline data file, inspections.db, along with the entity tables that I want to include in the database. I then initialize the SyncContext of the MobileService using this data store

var data = new MobileServiceSQLiteStore("inspections.db");
data.DefineTable<RealEstateProperty>();
data.DefineTable<Inspection>();

await MobileService.SyncContext.InitializeAsync(data, new MobileServiceSyncHandler());

Invoking a sync is actually a two part process. First you need to pull data down from the Mobile Service. Here we’re passing in a default table query (which will pull down all entities in the table), and using the name of the data type as the synchronisation key. I repeat this for both entity types I want to synchronize.

var propertyQ = MobileService.GetSyncTable<RealEstateProperty>().CreateQuery();
await MobileService.GetSyncTable<RealEstateProperty>().PullAsync(typeof(RealEstateProperty).Name, propertyQ);

var inspectionQ = MobileService.GetSyncTable<Inspection>().CreateQuery();
await MobileService.GetSyncTable<Inspection>().PullAsync(typeof(Inspection).Name, inspectionQ);

You’ll notice that I’m calling GetSyncTable instead of GetTable – this is because I want to reference the local offline table, rather than the Mobile Service endpoint. Now that I’ve pulled data down from the Mobile Service I can call ToListAsync on the sync table to retrieve all the elements that are contained in the offline table.

var props = await MobileService.GetSyncTable<RealEstateProperty>().ToListAsync();

Inserting items is a simple as creating them and inserting them into the sync table

var inspection = new Inspection
{
    InspectedBy = "Joe",
    RealEstatePropertyId = props[0].Id
};
await MobileService.GetSyncTable<Inspection>().InsertAsync(inspection);

Of course this only adds them to the local offline table. To push them up to the Mobile Service I call PushAsync on the synchronization context.
await MobileService.SyncContext.PushAsync();

Lastly to validate that the new items have appeared in the Mobile Service I can query it directly to get all items in the Mobile Service table

var inspections = await MobileService.GetTable<Inspection>().ToListAsync();

If you’re interested in what’s stored in the offline data file it can be found at C:\Users\<username>\AppData\Local\Packages\<package id>\LocalState and you can use a tool like SqliteStudio to view the contents of the database file

image

And you can use the SQL query window to write and execute sql to view the data.

image

Updating the Windows and Windows Phone Applications with the new Azure Mobile Service Entities

In my previous post I extended the Azure Mobile Service to include two entities, RealEstateProperty and Inspection. I’m now going to return to the Windows platform projects (ie Windows and Windows Phone) and update them to use these new entities.Rather than duplicate the entity definition I’m going to reuse the entity definition I created previously. Unfortunately, the base class of the two entities is a class called EntityData which is specific to Azure Mobile Service SDK for the full .NET Framework (ie to power the .NET backend services). This means we can simply move these entities into a class library, or better still a PCL, and reference it. Instead we’ll need to make the base class conditional on where the entities are being used – this is a great use for a Shared Project.

We already have a Shared Project which is used to share common code between the Windows platform projects. One option would be to simply reference this project from the service project but this would mean we couldn’t include any shared XAML or Windows platform specific code. Instead I’m going to create a new Shared Project which will be used to contain the entities that are going to be shared across both the Windows platform projects and the service project. To do this I need to download and install the Shared Project Reference Manager which extends Visual Studio to allow for the easy creation and referencing of Shared Projects. After installing the extension I simply add a new project as I would any other project type – right-click the solution node in Solution Explorer and select Add –> New Project. Select the Shared Project and give it a name, in this case will keep it inline with the other Shared Project by naming it RealEstateInspector.Shared.Entities.

image

With the Shared Project created, I need to add a reference to the Shared Project to both Windows platform projects and the service project – right-click the References node under the project and select Add Shared Project Reference. The two Windows platform projects should have both shared projects selected, whilst the service project should only reference the new Shared Project.

image

Next I need to move my entities out of the service project and into the shared project. I’ll also take this opportunity to change the base class, which as you’ll see will allow us to provide a different base class implementation depending on whether the entities are being compiled into the windows platform projects or the service project.

public class RealEstateProperty : BaseEntityData
{
    public string Address { get; set; }

    public virtual ICollection<Inspection> Inspections { get; set; }
}

public class Inspection : BaseEntityData
{
    public string InspectedBy { get; set; }

    public string RealEstatePropertyId { get; set; }
    public RealEstateProperty RealEstateProperty { get; set; }

}

The BaseEntityData class looks like this:

#if SERVICE
using Microsoft.WindowsAzure.Mobile.Service;
#endif

namespace RealEstateInspector.Shared.Entities
{
    public class BaseEntityData
#if SERVICE
       : EntityData{}
#else
    {
        public string Id { get; set; }
    }
#endif
}

You’ll notice that the BaseEntityData makes use of a compilation symbol to firstly control the base class (ie use the EntityData class if SERVICE is defined) and secondly whether the Id property is defined. The SERVICE symbol isn’t a predefined symbol so I’ll need to define that in my service project. I could have switched the logic to use one of the existing symbols, such as WINDOWS_APP but then if we ever extend this to other platforms, I’d have to modify the logic. It seems better to simply add a SERVICE symbol to the service project. Double-click the Properties node under the service project in Solution Explorer and then open the Build tab. Make sure you select All Configurations before adding SERVICE to the compilation symbols.

image

If I now go to the MainPage.Shared.cs (which I created in an earlier post) where we wrote the initial logic to query the TodoItems from the Mobile Service, I can update the code to instead use either, or both, the new entities we’ve defined:

protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var items = await MobileService.GetTable<Inspection>().ToListAsync();
    Debug.WriteLine(items!=null);
}

Whilst I’ve refactored the service code, there’s no reason to publish the new version since we haven’t modified the structure of the entities. However, there should be no harm in doing so if you’d like to keep the service up to date.

Adding a Relationship to the Azure Mobile Service Entity Model

After removing the TodoItem table and replacing it with a simple RealEstateProperty table (see previous post), the next step is to look at how I can add another related entity. I’m going to leverage the default behaviour exposed by Entity Framework using the Fluent API (see more on this in the article Code First Relationships Fluent API). To this end my entities will look like:

public class RealEstateProperty : EntityData
{
    public string Address { get; set; }

    public virtual ICollection<Inspection> Inspections { get; set; }
}

public class Inspection : EntityData
{
    public string InspectedBy { get; set; }

    public string RealEstatePropertyId { get; set; }
    public RealEstateProperty RealEstateProperty { get; set; }
}

And I’ll of course need to update the realestateinspectorContext:

public DbSet<RealEstateProperty> RealEstateProperties { get; set; }
public DbSet<Inspection> Inspections { get; set; }

The last code change I need to make is to add the InspectionController required to expose the data for this new table. To do this I could have duplicated the RealEstatePropertyController, renamed it and changed the generic type but this leads to quite a lot of unnecessary duplicate code. Instead with a little bit of refactoring I can abstract nearly all the code into a base controller:

public class RealEstateBaseTableController<TEntity> : TableController<TEntity>
    where TEntity : class, ITableData
{
    protected override void Initialize(HttpControllerContext controllerContext)
    {
        base.Initialize(controllerContext);
        var context = new realestateinspectorContext();
        DomainManager = new EntityDomainManager<TEntity>(context, Request, Services);
    }

    // GET tables/TEntity
    public IQueryable<TEntity> GetAll()
    {
        return Query();
    }

    // GET tables/TEntity/48D68C86-6EA6-4C25-AA33-223FC9A27959
    public SingleResult<TEntity> Get(string id)
    {
        return Lookup(id);
    }

    // PATCH tables/TEntity/48D68C86-6EA6-4C25-AA33-223FC9A27959
    public Task<TEntity> Patch(string id, Delta<TEntity> patch)
    {
        return UpdateAsync(id, patch);
    }

    // POST tables/TEntity
    public async Task<IHttpActionResult> Post(TEntity item)
    {
        TEntity current = await InsertAsync(item);
        return CreatedAtRoute("Tables", new { id = current.Id }, current);
    }

    // DELETE tables/TEntity/48D68C86-6EA6-4C25-AA33-223FC9A27959
    public Task Delete(string id)
    {
        return DeleteAsync(id);
    }
}

All I then need to do is inherit from this base class for my two controllers:

public class RealEstatePropertyController : RealEstateBaseTableController<RealEstateProperty> { }

public class InspectionController : RealEstateBaseTableController<Inspection> { }

With the updates to my data model I will of course need to add the appropriate migration by invoking the following in the Package Manager Console:

Add-Migration AddedInspections

I can now run the service project and when I invoke a GET on either controller the database will be upgraded using the new migration code.

One mistakes I came across in writing this post is that I had made the RealEstatePropertyId an int instead of a string. This of course meant my initial migration code setup a column that was an int which clearly couldn’t accept the guid id of the RealEstateProperty. There are two ways to handle this. I could have corrected the data model and run Add-Migration to create another migration. I find this to be a bit messy as the migration code will forever keep a record of my mistake. At this point, since I haven’t pushed this migration into production, I can easily undo the update to the database (essentially a backward/downward migration) and regenerate the AddedInspection migration. To undo the database update I have to invoke the following in the Package Manager Console:

Update-Database -TargetMigration 201501051134554_AddingRealEstatePropertiesToSchema

Here I’m specifying the last migration I want the database to roll back to, which in this case is the migration I created in my previous post. Once I’ve done this I call Add-Migration again:

Add-Migration AddedInspections –Force

Note that I’m including the –Force switch which will force the migration code to be fully regenerated, rather than just the designer code.

That’s all – I can re-run the application and it will apply the new migration (or you can just run Update-Database to migrate the database forward with the corrected migration).

Lastly, to create a Inspection I can again use Fiddler to invoke a POST method:

POST: http://realestateinspector.azure-mobile.net/tables/inspection
Content-Type: application/json
X-ZUMO-APPLICATION: wpxaIplpeXtkn-------------------------cg12

{"InspectedBy":"Fred","RealEstatePropertyId":"a7217f7e90b242f99f55cdef6b674c5d"}

This includes the RealEstatePropertyId of a property that exists in the database (since it’s a relationship) – if you attempt to use a value that doesn’t exist, you’ll get a 400 error back with an error which effectively says you’re attempting to violate the database schema.

Updating the Data Model with Azure Mobile Service

Whilst template and samples are great, often one of the hardest things is adapting the code to your particular scenario. One such example is with Azure Mobile Service when you decide that you want to change your data model for the first time. Firstly, the initial template that you download and publish to get an initial service up and running will create a ToDoItems table. Unless you happen to be building a ToDo task system then it is unlikely that you’ll want this table. So, how do we get rid of this table out of our Azure Mobile Service (and of course the SQL Server database that backs it)?

At this point a word of caution – this table was created by the Mobile Service, so don’t go messing with the table directly. For example you could use SQL Management Studio to connect to the SQL Azure instance and just delete the table but I think you’ll find that you run into some issues when you next run or attempt to deploy new versions of your Mobile Service. In fact, the Mobile Service template already provides a facility to do that. In fact, with any change to the Entity Framework data model the entire database structure will be dropped and recreated. This makes it really easy to remove the ToDoItems table, simply by commenting out the following line in the RealEstateInspectorContext:

//public DbSet<TodoItem> TodoItems { get; set; }

All I need to do now is publish and invoke the Mobile Service – I can do this by either running the Windows/Windows Phone applications wired up in the previous post or I can invoke it using Fiddler, as I did in an earlier post. It’s important to invoke the Mobile Service (even though it will fail with a 500 internal error because that’s what triggers the database initializer to kick in and restructure the database).

The next thing we need to change is that we don’t want to be dropping and recreating the database each time the data structure changes – this is a sure fire way in production to delete all that great app data! In the WebApiConfig.cs file there is a line which specifies the initializer for the database. In the template I downloaded this was already set as follows:

Database.SetInitializer(new realestateinspectorInitializer());

The realestateinspectorInitializer inherits from the generic class, ClearDatabaseSchemaIfModelChanges, which as you can imagine from the name is designed to clear up and recreate the database schema if the model changes (for example the above where we dropped the ToDoItems table). I’m going to change this to prevent the database being recreated; I’m going to start to apply migrations as I deploy new versions of my Mobile Service.

Note: In order to create the migrations that need to be applied you can use the tooling provided by the Entity Framework NuGet package via the package manager console. However, before you do this, make sure you run your Mobile Service locally with the TodoItems table comments out (don’t forget to invoke the service – just change the url in Fiddler to use localhost:XXXX where XXXX is the port number your service is running at). This will ensure you have a clean database to work from.

The first thing to do is to invoke Enable-Migrations from the package manager console (full details of the commands are available online - http://msdn.microsoft.com/en-au/data/jj591621.aspx). This will create a Migrations folder with a Configuration class and an initial migration, which assuming you have removed the TodoItems table will contain two empty methods, Up and Down.

Note: Make sure the Mobile Service project is the startup project for the solution when attempting to use the package manager console for generating migrations.

To use the Configuration class and the associated migrations I need to replace the following line:

Database.SetInitializer(new realestateinspectorInitializer());

with:

var migrator = new DbMigrator(new Configuration());
migrator.Update();

At this point you can run your Mobile Service but you will still see a 500 error since there is still no TodoItems table. In fact at this point we’re going to introduce a RealEstateProperty entity that we’ll be working with:

public class RealEstateProperty : EntityData
{
    public string Address { get; set; }
}

I need to add this to the realestateinspectorContext as follows:

public DbSet<RealEstateProperty> RealEstateProperties { get; set; }

At this point if I attempt to run the Mobile Service I’ll get an AutomaticMigrationsDisabledException and if I look further at the description it indicates that there are pending model changes that haven’t been applied to the database via a migration. Essentially it’s detected that my model doesn’t align with the database schema.

image 
Rather than hand craft the migration, which would be time consuming and rather mundane, I can again return to the package manager console and issue the Add-Migration command:

Add-Migration AddingRealEstatePropertiesToSchema

The “AddingRealEstatePropertiesToSchema” is a friendly name for this migration and a date-time stamp will be appended to the front of the newly created migration file eg 201501051134554_AddingRealEstatePropertiesToSchema.cs. This command in itself doesn’t update the database schema, all it does is determine the migration that needs to take place. To update the local database I can either call Update-Database, or simply run and invoke the Mobile Service. However, to do the latter I need to add a RealEstatePropertyController which will be the endpoint I’ll be invoking – the easiest way to do this is to simply rename the TodoItemController to RealEstatePropertyController, and change the generic parameter from TodoItem (this class can now be deleted) to RealEstateProperty.

When I run this I can now test the service by invoking a GET to http://localhost:51539/tables/realestateproperty (you may need to change the port number for your Mobile Service) which will of course return no data at this point but it doesn’t generate a 500 which means that it has run the migrations and that the model is aligned with the database schema. I can now publish this into my Azure Mobile Service and make a similar GET request to http://realestateinspector.azure-mobile.net/tables/realestateproperty. Don’t forget that you’ll need the X-ZUMO-APPLICATION header when calling a Mobile Service in Azure, whereas it is not required when running the Mobile Service locally.

The last thing I wanted to point out is that you can easily add data by issuing a POST command (don’t forget the Content-Type header)

POST: http://realestateinspector.azure-mobile.net/tables/realestateproperty
X-ZUMO-APPLICATION: wpxaIplpeXtkn-------------------------cg12
Content-Type: application/json

{'Address':'123 Sample Avenure, Random City'}

This should generate a 201 response if successful with a JSON body similar to the following (viewed using the JSON pane in Fiddler)

image

My service is starting to feel like it is more realistic now, although very simplistic. I’ll need to extend this model quite a bit more and then update the applications to access the data from it.

Connecting Windows/Windows Phone Apps to Azure Mobile Service

In my previous post I created Windows and Windows Phone applications using the universal app template, and created and published a Mobile Service, The next step is to connect the apps to the Mobile Service using the Windows Azure Mobile Service NuGet package. In my solution I simply right-click on the solution node and select manage NuGet Packages. Locate the NuGet package by searching for “azure mobile service” and click Install next to the SDK package. Add the SDK to both Windows and Windows Phone projects but not the Service project.

image

Add a new file to the Shared project, MainPage.shared.cs and replace the MainPage class definition with the following:

public partial class MainPage
{
    public static MobileServiceClient MobileService = new MobileServiceClient(
            "
https://realestateinspector.azure-mobile.net/",
            "wpxaIplpe---------------------lZAPYQEBcg12"
    );

    protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        var items = await MobileService.GetTable<TodoItem>().ToListAsync();
        Debug.WriteLine(items!=null);
    }
}

public class TodoItem
{
    public string Id { get; set; }
    public string Text { get; set; }
    public bool Complete { get; set; }
}

I can run either the Windows or Windows Phone application and see that the items variable gets populated with the contents of the TodoItems table. Of course we need to switch out this table with one that is more applicable to the property inspector application I’m building but this demonstrates how easily you can retrieve data using the Azure Mobile Service SDK.

Creating Your Solution and Your Azure Mobile Service

As I discussed in my initial post there are a number of components that make up the property inspection tool. In this post we’ll start by creating the initial solution structure, create and add in the Azure Mobile Service, and publish the Azure Mobile Service.

Initial Solution Structure

A lot of blog posts will start by creating the Azure Mobile Service and then use the template projects provided on the home page of the newly created Mobile Service. Sometimes this isn’t an option and you want to be able to integrate a Mobile Service into an existing application. For this reason I’m going to start with a new project creating Visual Studio using the Blank App Universal template.

image

This will create Windows and Windows Phone projects, with a Shared code project to handle files shared between the two applications.

image 

 

Creating the Azure Mobile Service

The next step is to create the Azure Mobile Service. This can actually be done by right-clicking on the Mobile Services node in the Server Explorer window in Visual Studio but I’m going to have to go to the management portal to download the initial project for the Mobile Service anyhow. To create the Azure Mobile Service, navigate to the Azure Management Portal and select New >> Compute > Mobile Service > Create from the toolbar at the bottom of the screen. Complete the setup wizard – make sure you select the .NET backend.

image

After completing the setup wizard, a few moments later the new Mobile Service will be available. However, before I can use it I need to publish the set of services -  you can think of what I’ve done so far as just setting up a placeholder for where the services will live.

Publishing the Mobile Service

To publish the Mobile Service I expand out the Get Started section on the home page of my newly created Mobile Service, and click on the Download link. I save the downloaded zip file, unblock and then extract the zip file.

image

I then copy the service folder (in my case realestateinspectorservice) into the solution folder of the solution I created earlier. Back in Visual Studio I then add the existing realestateinspectorservice project into the solution.

image

Right-click on the services project and select Publish. Select Microsoft Azure Mobile Services as the publish target

image

At this point if you’re not already signed in, you’ll need to sign into you Azure subscription with your Microsoft Account in order to select the previously created Mobile Service:

image

After selecting the Mobile Service to publish to, click OK and then the Publish button. This will cause the project to be compiled (and any required NuGet packages to be downloaded) and then published up to the Mobile Service. This may take a few minutes the first time as all referenced libraries will have to be copied up. However, future publish operations will be significantly quicker as they are by default differential.

After publishing the Mobile Service I can test that it’s operational using Fiddler (or curl etc) to simulate a GET request. I need two pieces of information: firstly the url of the Mobile Service I created. This can be found either in the Output window of Visual Studio at the end of publishing the Mobile Service, or from the dashboard pane of the Mobile Service in the Azure portal. The second thing is that I need one of the two assigned access keys. This again comes from the Azure management portal by clicking on the Manage Access Keys button in the toolbar at the bottom of the page. This key needs to be added to the request as the X-ZUMO-APPLICATION header. The following images show the request and response samples

 

image

image

 

So this gets me part of the way through setting up my solution – the next thing to do is to connect the Windows and Windows Phone applications so that they can call out to the Mobile Service…..

Field Engineer Sample for Azure Mobile Services

Over on the Windows dev center there is a code sample, Field Engineer, which covers a good portion of the application scenario I painted in my previous post. I won’t be delving into the sample in too much detail but I did want to do a quick review of the solution structure so that you get an idea of what’s there and what I’ll be adding to my scenario that extends this sample.

image

The sample solution in made up of four projects and only offers a Windows application frontend (in contrast to my scenario where we want to support both native apps and a web frontend). The mobile services are in the Services project which has an accompanying Test project. The interesting thing about the test project is that it does raw httpclient calls to validate that the services work as expected, instead of using the Azure mobile service client wrapper classes. Lastly there is a Setup project which is simply a command line utility that is designed to assist in the setup of the Azure components required in order to run this sample.

I’d highly recommend downloading this sample, setup and run it (follow all the instructions otherwise it’s not likely to work), before we move onto exploring my scenario in the coming posts.

Mobile First, Cloud First and How it Applies to Line of Business Software

I’m going to start the year by dissecting a typical business scenario which will demonstrate how the use of Windows, Windows Phone and Azure can be plugged together to quickly deliver a line of business solution. Throw in a bit of Xamarin and a web front end and you have a solution that will enable employees to use any device they choose in order to access the software.

The first thing to cover is the scenario, which in this case is going to be a property inspection tool that could be used by a property manager to do periodic property inspections required under most rental agreements. At first glance this appears to be a tool that is specific for the real estate industry but as we’ll see there are a number of components that make it similar to any task, defect or issue tracking system:

- Property managers will have a number of properties assigned to them to manage
- Properties will have a history of inspections which may include images and/or videos
- Property information, and perhaps most recent inspection, needs to be available offline (just in case there is no internet inside a property being inspected)

- Inspections need to be able to be created, edited and submitted from a mobile device

This will probably do for the time being; as we go we may introduce other elements to demonstrate the use of various platform components. What’s interesting to note at this point is that properties can be switched out for projects, and inspections for tasks, if this scenario were a task/issue/defect tracking system.

At a high level let’s discuss the major components:

- Mobile devices – Naturally as .NET developers we gravitate to what’s easiest so we’ll include Windows and Windows Phone applications based on the universal app template which uses a shared code project to prompt reuse. However, we shouldn’t neglect the other platforms so we should include iOS and Android projects, using the Xamarin tooling. Our business logic we’ll abstract into a portable class library (PCL) to attempt to give us maximum reuse.

- Services – Azure Mobile Services will give us the raw scaffolding to stand up a SQL Server backend with services exposed to surface data to our mobile applications. These services support synchronisation which we’ll use to give the mobile applications offline support.

- Blobs – Azure Blob Storage will be used to store the images and videos collected as part of the solution. Whilst the service tier will be used to control access to Blog Storage (by issuing Shard Access Signatures) the upload will be done from the mobile applications directly into blob storage

- Authentication – As this is a line of business solution we’d prefer users to not have to remember another set of credentials. To this end the solution will use Azure Active Directory (AAD) to authenticate users and grant them access to the software. The users can be synchronised from the corporate AD into AAD so as to maintain a single set of credentials for any user.

- Web application – An Azure Website will be used to provide desktop and mobile solution for those unable to use the mobile applications. Whilst this could go directly to the SQL Server backend, it will in fact be routed via the service tier to ensure a common authentication pattern and usage model for the data.

- Scheduling – A scheduler will be setup in Azure for use by the solution in order to schedule particular jobs or operations to be carried out. For example the periodic generation and sending of reports.

- Push Notifications – When new data is available, push notifications can be sent out to the mobile applications to either alert the appropriate user, or perform a background synchronisation of the new data.

I’ll use this post as a reference for the components that I’ll be discussing in the coming posts. The components aren’t in any particular order and the posts won’t focus on individual components, rather how they connect together and what you need to know to get them to work together.

“Ello” who built this rubbish

So after requesting an invite so long ago that I’d forgotten I had a passing interest in the site, I final received in invite via an email from someone called Todd, who I can only assume is related to the site somehow. Anyhow, after signing up on my mobile I wasted a couple of minutes attempting to browse the site and work out how to do simple things like post. In the end I figured I must be missing something, or that perhaps the site wasn’t rendering properly on my Windows Phone. That was a day or so ago; today I remembered that I was supposed to go back and take a look on my laptop. In doing this, again I was woefully disappointed. So much so that I went out looking to see what others had said about the site. The good news is that I’m not alone – for example a post by the Lion of the Blogosphere (http://lionoftheblogosphere.wordpress.com/2014/10/02/review-of-ello/comment-page-1/) sums it up nicely:

But now let’s get to the part about Ello that sucks. The website is a confusing buggy piece of crap. It took me an hour to figure out how to post a photo and two paragraphs of text under it.

I couldn’t have said it better myself. What a complete waste of my time. The site might look ok but the UX is dreadful – there’s no clear call to action; nowhere to start on the page; no obvious way for someone new to get started.

Anyhow, I think I’ve hated enough on this site – needless to say I won’t be going back in a hurry.

Visual Studio GenerateResource Error Building on Windows 10

A couple of weeks ago when I installed Windows 10 on my primary machine I ran into an issue where Windows Phone/Windows/Universal applications stopped building due to a rather cryptic error relating to trusted network resources…. which was bizarre since the projects were all local on my machine. This is the same error reported on the Windows Dev Center - https://social.msdn.microsoft.com/Forums/windowsapps/en-US/82fea1c9-ae5a-4595-a2c1-46efb853303b/error-2-generateresource?forum=wpdevelop.

The good news is that there’s a relatively simple fix as indicated in the error message ”please enable the loadFromRemoteSources switch". Of course this shouldn’t need to be applied but that’s the danger of running on the edge with a pre-release product. What’s not obvious is where the switch should be applied – if you follow the link to MSDN it seems to indicate that the switch needs to be added to Devenv.exe.config, which does nothing to fix the issue. Turns out you need to add it to the MSBuild configuration file (eg C:\Program Files (x86)\MSBuild\12.0\Bin\ MSBuild.exe.config).

<?xml version ="1.0"?>
<configuration>
    <configSections>
        <section name="msbuildToolsets" type="Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </configSections>
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
    </startup>
    <runtime>
    <loadFromRemoteSources enabled="true"/>
    ….

Demo rule #1 practice again and again and again, particularly the night before….

Tomorrow is round 2 of TechEd Australia and after my demos all seemed to go well in Melbourne I figured I was all set. However as I usually do I wanted to double check that everything was going to work (particularly since I’m running the Windows 10 preview build). Anyhow, it’s a good thing I did because the wonderful Azure team have changed the syntax of one of the manifest files I have to manually edit mid-way through my first session. The step I walk through is actually taken from a post over on Azure Mobile Services site (http://azure.microsoft.com/en-us/documentation/articles/mobile-services-windows-store-dotnet-adal-sso-authentication/) and includes this change:

image

Well, no more – if you try to do this you’ll find that the appPermissions node doesn’t exist in the manifest file. Luckily I have a working mobile service with this change already applied, so I figured if I download the manifest file I should be able to see what’s changed. It turns out that the syntax has changed and that instead of replacing the appPermissions node, you now have to replace the oauth2Permissions node ie change:

"oauth2Permissions": [],

to

"oauth2Permissions": [
    {
      "adminConsentDescription": "Allow the application access to the mobile service",
      "adminConsentDisplayName": "Have full access to the mobile service",
      "id": "b69ee3c9-c40d-4f2a-ac80-961cd1534e40",
      "isEnabled": true,
      "origin": "Application",
      "type": "User",
      "userConsentDescription": "Allow the application full access to the mobile service on your behalf",
      "userConsentDisplayName": "Have full access to the mobile service",
      "value": "user_impersonation"
    }
  ],

The upshot of this is that had I just assumed that my demos would all just work tomorrow I would have been fighting this fire on stage (argh). Moral of the story is practice, practice and practice some more – you never know when the demo gods will strike, and it’s best to be prepared when they do.

TechEd Australia – Sydney and Melbourne 2014

TechEd1

This year I’m delivering two sessions in both Melbourne (7-8th October) and Sydney (27-28th October):

Using Visual Studio and Blend to build Beautiful Universal Applications (WPD307)
The new Universal Application project promises to reduce the amount of code you need to write, but does it reduce the amount of design work you have to do? In this demo-heavy session, XAML guru Nick Randolph explores the tooling available in Blend and the patterns you’d use to produce stunning Universal Applications with a minimum amount of work.

Building and Migrating Modern Enterprise Line of Business Applications (WPD304)
Mostly, when we build enterprise applications, we’re not starting from scratch. Deciding what to build, what to reuse and what to keep is an important part of the enterprise software development decision process. In this session, Nick will explore the conditions and requirements that might lead you to decide which of these approaches to take. He’ll also demonstrate some techniques for taking an existing Line of Business application and lighting it up with a modern, touch-friendly UI.

 

If you’re attending in either session, come along and chat about the direction of the Windows platform and how to take advantage of it in your business.

Errors Installing and Running Windows Phone 8.1 Appx

Last week we ran into a couple of issues installing and running a Windows Phone 8.1 Appx application. Here are some of the symptoms:

  • Application deploys and runs fine in the emulator
  • Application deploys and runs fine on some phones running Windows Phone 8.1 but refused to install on other phones. The error given by Visual Studio when attempting to install the application was a rather cryptic, and overly useless, error code
  • Application package could be successfully signed using the signing tool as part of the SDK
  • Signed application package refuses to install on some retail phones running Windows Phone 8.1

It turns out that we were referencing the Active Directory Authentication Library which in turn was making a native call that only showed up when we ran the WACK test. As we weren’t planning to deploy via the Windows Store we hadn’t run the WACK test recently and it was only by chance that I ran it to see if it threw up any errors. Fixing the errors and warnings not only addressed the installation issue it also highlighted some issues with the project structure (incorrect images sizes etc).