13Mar/1324

Preview of the new Managed Client for Windows Azure Mobile Services

Note: This is my personal blog. Although I’m currently doing an internship at Microsoft and this post is about a product released by Microsoft I worked on, the opinions on this blog are my own. They do not represent the opinions of Microsoft in any way.

Update: Carlos Figueira has a detailed list of breaking changes at his blog.

Update 2: We published an update to fix the issues with Windows Phone 7.5. The update can be found here.

Today we are releasing a pre-release version of the new Managed Client for Windows Azure Mobile Services on NuGet. This release adds several new features and also adds support for Windows Phone 7.5.

The managed client now supports the following platforms:

  • Windows 8
  • Windows Phone 8
  • Windows Phone 7.5
  • Portable class libraries.

Windows Phone 7.5 support and Portable Class Libraries have been among the top requested features by our customers!

uservoice

Great! How do I get it?

The preview is available as a pre-release NuGet package. To use the package you need at least NuGet 2.1.

Note: This version is not officially supported. The latest officially supported client is available as a stable NuGet package or as an extensions sdk.

nuget-pre

To be able to see the package in Visual Studio you need NuGet 2.1 and you need to explicitly tell Visual Studio to show you pre-release packages.

includepre

New features

Beside support for new platforms and bug fixes, this release also adds a bunch of new features:

  • Enum support. Enum types are now supported in queries and for serialization. Enums will be serialized automatically into strings by the client. If for some reason you want to serialize enums as integers, you can still use the following technique to expose the enum as int for serialization.
[JsonProperty("value")]
public int ValueInt { get; set; }

[JsonIgnore]
public EnumType Value { get; set; }
  • Nullable types. Nullable types are now fully supported for queries and serialization. You can read more about Nullable Types here.
  • Contains support in queries. We already supported string.Contains in queries, but now you can also write Contains queries on lists. These queries will now automatically be translated into a sequence of “or” statements:
List names = new List() { "John", "Tom" };
from p in table
where names.Contains(p.Name)
select p
  • MobileServiceCollection. We added a new collection that replaces our previous MobileServiceCollectionView. This class had some problems and was less portable going forward. You can read more about the new collection further on.
  • HttpMessageHandlers. Service Filters available in our previous release are now replaced by HttpMessageHandlers. These classes are part of the recently released HttpClient library and are reusable by everything that uses HttpClient. More on this also further on.
  • Improved unit-testability. We removed the sealed keyword from most of the public facing classes and added interfaces for some of them. This heavily improves the unit testability of the library for us and make it easier for developers to substitute our classes for mocks.

Portable Class libraries

Currently we have separate clients for Windows and Windows Phone 8. This release unifies these platforms by moving towards a Portable Class Library. Portable Class Libraries offer several advantages for developers, since they can now share their codebases using Mobile Services more easily between the different platforms. Also it allows us to rollout changes faster and brings consistency across the supported platforms. You can read more about Portable Class Libraries on MSDN.

Our portable library targets:

  • Windows Store apps
  • Windows Phone 7.5 and higher
  • .Net 4.5
  • Silverlight 4 and higher

This does not mean we support all these platforms. The Portable Class Library need a platform extension assembly to work correctly and it won’t work without it. We only provide platform extension assemblies for Windows Phone 7.5, Windows Phone 8 and Windows Store apps. If you need to support other platforms, you can get the source code from GitHub. More on platform extension assemblies further on. We are considering adding .Net 4.5 support in the future.

Architecture

Although Portable Class Libraries are a great addition to the Managed Mobile Services client, we cannot move all of our code into the Portable Class Library. Some functionality is only available on one platform and other functionality differs between platforms. Therefore, to be able to use the new Managed Client you also need a platform specific assembly, which contains code to be able to use features available on that specific platform. UI authentication is an example of a feature that works different on different platforms and is not portable.

diagram

The design of the managed client is roughly as shown in the diagram. For you as a developer this means you need two assemblies for your Windows Store app to use Mobile Services. For Windows Phone this works a little different. For Windows Phone there is an additional assembly. This assembly contains functionality which is not allowed in background agents. In our case that means that login functionality involving UI lives there. So, if you install this package into a background agent project, make sure to remove the reference to Microsoft.WindowsAzure.Mobile.UI.dll.

With the platform extension assemblies we take an approach similar to what the Reactive Extensions team earlier did with Rx 2.0. We are constantly evaluating what platforms to support with our Portable Class Library with respect to the functionality we can actually put in the portable part, because support for more platforms in general means we have to move more functionality to the platform extension assemblies.

A new collection

MobileServiceCollection is our new collection type that replaces MobileServiceCollectionView going forward. The functionality it offers is similar to its predecessor and it offers more extensibility.

  • Support for paging. Simply give the collection a page size as part of the constructor and it will request the data in batches.
  • Client-side LINQ queries. We acknowledge that OData does not cover all query scenarios for users. To make this as easy as possible you can specify a custom selector function over the data after it has been retrieved from the server. This can be useful for example to wrap your Model objects into a ViewModel before insertion or to do grouping.
  • ISupportIncrementalLoading for Windows Store apps. Some controls in the Windows Runtime support an interface called ISupportIncrementalLoading. This interface allows controls to request extra data when the user scrolls. We have built-in support for this interface for Windows Store apps. Our windows store extension assembly contains the MobileServiceIncrementalLoadingCollection which automatically handles the calls from the controls.

To use the new collection you can simply use our ToCollection() extension methods on IMobileServiceTableQuery<T> and IMobileServiceTable<T> or use on of the available constructors for more customizability.

To actually load data you have to call LoadMoreItemsAsync(). When you have specified a page size before, the collection will only retrieve so much items as you specified, otherwise it will just send the original query to the server. Make sure you always await the calls to LoadMoreItemsAsync and wrap it with a try { } catch { } to handle any exceptions from the server.

MobileServiceCollection<TodoItem, TodoItem> collection = await client.GetTable().ToCollectionAsync();

or with page size 10:

MobileServiceCollection<TodoItem, TodoItem> collection = await client.GetTable().ToCollectionAsync(10);

Note that to load more pages you have to call LoadMoreItemsAsync() yourself.
If you want to do paging in a Windows Store app, you can also use the MobileServiceIncrementalLoadingCollection<TTable, TCol> which implements ISupportIncrementalLoading. For this class you cannot specify a page size since the controls automatically request a number of items. You also do not need to call LoadMoreItemsAsync() since the control will call this method for you.

If you want to do paging on a platform other than the Windows Store you currently don’t have ISupportIncrementalLoading. Instead you have to wire this up yourself. For Windows Phone you can use Scroll Compression states and call LoadMoreItemsAsync yourself.

HttpClient

In this release we are replacing Service Filters, on the Managed C# client, with HttpMessageHandlers which are part of HttpClient. HttpClient offers several advantages over our previous implementation and HttpMessageHandlers allow developers to reuse their handlers for other projects using HttpClient.

ServiceFilters can be easily transformed into HttpMessageHandlers. Consider the following filter created by Josh Twist:

public class BusyServiceFilter : IServiceFilter
{
	private int _callCount = 0;
	private Action _busyIndicator;

	public BusyServiceFilter(Action busyIndicator)
	{
		_busyIndicator = busyIndicator;
	}

	public IAsyncOperation Handle(IServiceFilterRequest request, IServiceFilterContinuation continuation)
	{
		return HandleAsync(request, continuation).
			  AsAsyncOperation();
	}

	private async Task HandleAsync(IServiceFilterRequest request, IServiceFilterContinuation continuation)
	{
		// update the count by one in a single atomic operation. 
		// If we get a 1 back, we know we just went 'busy'
		var outgoingCount = Interlocked.Increment(ref _callCount);
		if (outgoingCount == 1)
		{
			_busyIndicator(true);
		}

		IServiceFilterResponse response = await continuation.Handle(
			request).AsTask();

		// decrement the count by one in a single atomic operation.
		// If we get a 0 back, we know we just went 'idle'
		var incomingCount = Interlocked.Decrement(ref _callCount);
		if (incomingCount == 0)
		{
			_busyIndicator(false);
		}

		return response;
	}
}

This filter creates a busy indicator based on in-flight requests. It can be easy transformed into an HttpMessageHandler. The following sample show an HttpMessageHandler which does the same. Custom HttpMessagehandlers should in most cases derive from DelegatingHandler as they are meant to be “pass-through”.

public class BusyHandler : DelegatingHandler
{
	private int _callCount = 0;
	private Action _busyIndicator;

	public BusyHandler(Action busyIndicator)
	{
		_busyIndicator = busyIndicator;
	}

	protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
	{
		// update the count by one in a single atomic operation. 
		// If we get a 1 back, we know we just went 'busy'
		var outgoingCount = Interlocked.Increment(ref _callCount);
		if (outgoingCount == 1)
		{
			_busyIndicator(true);
		}

		HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

		// decrement the count by one in a single atomic operation.
		// If we get a 0 back, we know we just went 'idle'
		var incomingCount = Interlocked.Decrement(ref _callCount);
		if (incomingCount == 0)
		{
			_busyIndicator(false);
		}

		return response;
	}
}

Breaking Changes

The switch to HttpClient, the Portable Class Library and the new collection are breaking changes compared to our previous client, but we believe they all benefit developers.

Other breaking changes we made include a switch to Json.NET. While we did our best to keep the behavior the same, there are small changes that could affect you. Most of them actually make your life easier. For example Uri instances can now be serialized without a custom converter.

We also fail early when you try to send numbers, such as longs, ulongs and decimals, to the server which can’t be handled by the server because the number is too large or needs too much precision. As most of you will know, our server runtime is running on JavaScript, in which every number is a double. This means for example you can’t send a long to the server which is greater than 2^53.

exception

Our behavior with multiple calls to Skip(int) and Take(int) has also changed. Multiple Skip calls will now add up, so Skip(10).Skip(8) will result in Skip(18). Multiple calls to Take(int) will result in the lowest being used, so Take(2).Take(30) will result in Take(2). This makes our API consistent with other OData client libraries such WCF Data Services.

More about breaking changes here.

Pre-release

As mentioned before, this is a pre-release of our new library. Things are likely to change between now and the stable release, although we always try to keep the public changes at a minimum. We do NOT recommend the use of this library if you have critical business depending on it, as it is likely to have bugs and is not officially supported.

This release is meant for testing purposes and for us to get feedback on the changes we made. Try it out if you have the chance and submit your feedback and bugs via the forums!

NuGet

This pre-release client is only available on NuGet. Did I already mention you need NuGet 2.1 for it to work? Otherwise Portable Class Libraries and Windows Phone 8 won’t work. If you receive errors such as:

6507_NuGetFailedNeedsUpdate_thumb_3C41099C

Then you need to update your NuGet version via Tools -> Extensions and Updates.

8662_ExtensionsAndUpdates-2_thumb_3BD4D6A7

What’s next?

We plan to update the NuGet package regularly with the latest bug fixes and improvements. Stay tuned for more things to come in the months ahead!

Johan Laanstra (SDE Intern, Windows Azure Mobile Services)

Did you like this? Share it:
Comments (24) Trackbacks (12)
  1. Hi,

    Is the feature “Contains support in queries.” is a change on the server or I need to get the new library?

    FYI, the HttpClient PCL does not have a license to use it in a production code.

    Thank you
    ArchieCoder

    • “Contains support in queries.” is a feature of the client. It is translated into a series of ‘or’ statements.
      HttpClient for portable libraries is indeed pre-release as is this library.

      Johan

  2. I am having this nasty exception when creating a client in the App.xaml.cs:
    public static MobileServiceClient MobileService = new MobileServiceClient(“mobile service”, “my key”);

    I am using VS2010 with WP7.5 and using the Windows Azure Mobile Services 0.3.1-alpha version

    The type initializer for ‘Microsoft.WindowsAzure.MobileServices’ threw an exception.

    • Make sure you have a reference to Microsoft.WindowsAzure.Mobile.Ext for Windows Phone 7.5

      Johan

      • I have the dll (source: packages\WindowsAzure.MobileServices.0.3.1-alpha\lib\sl4-windowsphone71). I am not sure what I am missing here. It crashes at the very start. Is there any sample that runs with this version in WP7.5?

      • I had the same problem. I did not understood that I must use NuGet to install WindowsAzure.Mobile on both my Project.
        I first using NuGet on my Portable Class Library Project, without also installing WindowsAzure.Mobile to my WP7.5 Project. Then I got error.
        After install WindowsAzure.Mobile using NuGet on my WP7.5 project, the Microsoft.WindowsAzure.Mobile.Ext was installed, and that fixed the problem.

  3. how do I convert this method from wp8 to wp7.5 compatible

    private void RefreshTodoItems()
    {
    // This code refreshes the entries in the list view be querying the TodoItems table.
    // The query excludes completed TodoItems
    items = todoTable
    .Where(todoItem => todoItem.Score > 1)
    .OrderByDescending(todoItem => todoItem.Score)
    .ToCollectionView();
    //items = todoTable.ToCollectionView();
    ListItems.ItemsSource = items;
    readScore();
    }

    • That’s very easy. You need to change ToCollectionView() into ToCollectionAsync(). This call needs to be awaited so you need to make your Refresh method async. Make sure you wrap the await in a try { } catch { } to handler any exceptions.

      • private async void RefreshTodoItems()
        {
        // This code refreshes the entries in the list view be querying the TodoItems table.
        // The query excludes completed TodoItems
        items = todoTable
        .Where(todoItem => todoItem.Score > 1)
        .OrderByDescending(todoItem => todoItem.Score)
        .ToCollectionAsync();

        await items.LoadMoreItemsAsync();
        //items = todoTable.ToCollectionView();
        ListItems.ItemsSource = items;
        readScore();
        }

        I have an error on .ToCollectionAsync()
        says I cant implicitly convert type system.threading.task<mobileservice<…
        to mobileservice<…

        • I fixed that. added await before todoTable.

          Im trying to test now, but am getting a MethodAccessException in the line public static MobileServiceClient MobileService = new MobileServiceClient(
          “my mobile service link”,
          “my mobile service key”
          );

          this line is in my xaml page that shows mobile service data.

          • I am having very similar issue. I can not initialize the client in the app.xaml file either.

          • First make sure your nuget version is up to date and make sure the project at least references Microsoft.WindowsAzure.Mobile and Microsoft.WindowsAzure.Mobile.Ext.

            If you are sure these two things are correct and you still have problems, please post this on the forums including details about the platform you are building for (wp8/wp7/win8), libraries you reference, visual studio version etc.
            Even better: provide a sample project that shows the problem.

            Johan

          • those are uptodate. my target os is 7.1, cant do 7.5.

          • We have published an update. 0.3.2-alpha should fix the issues you are having with Windows Phone 7.5.
            Let us know via the forums, if you have any other issues!

            Johan

        • Yeah 🙁 Getting same error. Used both .ToCollectionAsync() and .ToCollectionAsync(). I’m using WP 8.0 as client.

        • Free knowledge like this doesn’t just help, it promote deamcrocy. Thank you.

  4. Hi

    This is what I was looking for, but as usual when I try something (I’m stupid) it fails.

    I wish there was an example Project or an step by step guide to show how to use this.

    In my Example I have 3 Project
    One Windows Phone 7.5 project
    One Windows Store project
    One Portable Class Library Project (who I call MyPortableLibrary)

    Windows Phone and Windows Store Project both have Reference to MyPortableLibrary.

    I used NuGet and install Microsoft.WindowsAzure.Mobile in MyPortableLibrary. Then in MyPortableLibrary I created the MobileServiceClient and used it to insert some data in Azure.

    I call the methode I created in the MyPortableLibrary who insert data in Azure, from the Windows Phone 7.5 Client (who has Reference to MyPortableLibrary).

    When I trie it, I got the Message:
    “A Windows Azure Mobile Services assembly for the current platform was not found. Ensure that the current project references both Microsoft.WindowsAzure.Mobile and the following platform-specific assembly: Microsoft.WindowsAzure.Mobile.Ext.”

    I se from other comment that someone else have the same problem, and I se the solution is to have an Reference to Microsoft.WindowsAzure.Mobile.Ext.

    My first question: Where should I have the Reference, in the Mobile Project, Store Project, Portable Class Library, or in every Project?
    My Secound question: Where do I find Microsoft.WindowsAzure.Mobile.Ext . Do I use NuGet?

    For someone this question sound stupid, but for me it’s a show stopper.

    Hope someone can help me, thanks!

  5. How can I use azure mobile services with silverlight 4? I tried via webclient and had no success.

  6. I’m trying to bind a mobileservicecollection to a listbox, but I can’t get it to work. If I bind a observable collection filled with items from the mobileservicecollection it does work. I’m using a modelviewmodel. Any ideas on this?

    http://stackoverflow.com/questions/16911582/mobileservicecollection-data-binding-to-listbox

    I’m running 7.8

  7. Fine way of describing, and good post to take facts concerning
    my presentation focus, which i am going to deliver in school.


Leave a comment