Json.NET, Android/Xamarin and date serialization

In case you are using JSon.NET with Android/Xamarin you might encounter an “Object null reference” exception when trying to serialize (and probably deserialize as well) a type that contains DateTime property. The null object in question is TimeZoneInfo.Local.

This error happens when Android has no time zone set and thus Xamarin doesn’t set that property because it doesn’t know what time zone to use. There is a simple test where you can inspect Android’s time zone settings, just fire this command line:

adb shell getprop persist.sys.timezone

If it returns a blank line it means you are in trouble. A simple workaround for development is to set manually Android’s time zone through Settings/Date & Time or just fire another command line (i.e. setting time zone to Belgrade):

adb shell setprop persist.sys.timezone Europe/Belgrade

This works when using Genymotion emulator. Other than this there is no way to manually set the TimeZoneInfo.Local (perhaps it might be set through reflection, didn’t try it) which means your application won’t work in affected devices. Luckily the bug has been fixed and Xamarin will default to time zone defined by Java.Util.TimeZone.Default.ID. So, hopefully, the problem will go away for good.

A memory profiler for Xamarin.Android

Here is a first ever snapshot of my home-grown memory profiler for Xamarin.Android.

While very spartan it does the core job – comparing two snapshots for objects with growing instances (aka memory leaks). An array of Autofac.Core.IRegistrationSource[] is showing its references (one root, one to a List<>).

There you. Interested?

PS. Sample features DevExpress WPF components, chiefly XpfGrid.

Annoying problem that prevented comments on blog fixed. Hopefully.

Looks like I've finally fixed a problem that prevented you to comment on my/this blog. It was caused by blogengine.net's TypePadFilter extension that, when unconfigured, was throwing an uncaught exception that was propagated to the user that initiated comment save.
Here is my feedback on the issue. Hopefully the blogengine.net crew will make the posting comment less error prone by embedding all calls to extensions with a try/catch clause.
Anyway, fire comments away - good or bad. And please, let me know if there are still problems.

Using Autofac with Xamarin

Good news is that Autofac, my IoC container of choice, works with Xamarin and even within Portable Class Library.  However there is one potential pitfall and it seems it happens at least when you use factories.

Imagine resolving ITubo defined as:

public class Tubo: ITubo
{
    public Tubo(Func<ITubo> tuboFactory)
    {}
}

public interface ITubo
{}

Note the use of factory through Func<ITubo>. In this case Autofac uses reflection and perhaps some runtime IL code generation. Now, try running the following piece of code on Xamarin.Android:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<Tubo>().As<ITubo>();
var container = builder.Build();
container.Resolve<ITubo>();

It is simple registration and after that I do resolve the interface. When you run this code it will most probably work. But that’s only because you are running it in Debug configuration. Now try running in in Release configuration. It will most probably throw an exception at you:

Autofac.Core.DependencyResolutionException: An exception was thrown while executing a resolve operation.

Not very informative but at least the call stack shows that problem happens within System.Core assembly. And it isn’t Autofac’s fault at all.

The reason for the problem is simple but perhaps not the most obvious one. Default project settings are that at Release configuration it cuts out all of the unused code from SDK libraries (Xamarin stuff which is basically all .net BCL) and combines all of the assemblies into a single file - through its linker (at Debug time it uses shared libraries as would .net on Windows). And since Autofac is doing operations at runtime (at least when it comes to factories), linker doesn’t see those and simply cuts off unused types at compilation time to reduce the output size. Read more about Xamarin linking process here:

Linking

The nasty part is that you won’t know what types are cut off until you run the application in Release configuration. Remember, always try your applications in Release configuration!

The solution

Anyway, the solution is, as I’ve found out, rather simple. Just instruct linker to leave alone (don’t optimize) System.Core assembly. If you are using Visual Studio the go to Project/Properties, Android Options tab and enter System.Core text into Skip linking assemblies text box. If you are using Xamarin IDE the go to Project/Properies, Build/Android Build tab, Linker subtab and enter the same System.Core into Ignore Assemblies text box (didn’t try this one). That’s it, linker will leave alone that assembly and Autofac will happily run even in Release configuration.

Luckily the difference in output file size isn’t that significant: 450KB in worst case.

Invoking DatePickerDialog asynchronously with Xamarin.Android

Invoking a DatePickerDialog in Xamarin.Android is a bit tricky because it is done through callbacks and at the end one has to dispose it as well. Hence I present asynchronous extension methods PickDateAsync and PickDateAndAssignAsync.

With my code you can use this syntax and don’t worry about DatePickerDialog disposal:

EditText et1 = FindViewById<EditText>(Resource.Id.editText1);
await et1.PickDateAndAssignAsync();

There is also an overload that accepts an instance of CancellationToken. Here are the methods:

public static class DatePickerExtension
{
    public static Task<DateTime> PickDateAsync(this EditText dateEdit)
    {
        return dateEdit.PickDateAsync(CancellationToken.None);
    }
    public static Task<DateTime> PickDateAsync(this EditText dateEdit, CancellationToken ct)
    {
        TaskCompletionSource<DateTime> tsc = new TaskCompletionSource<DateTime>();
        DatePickerDialog picker = null;
        DateTime current;
        if (!DateTime.TryParse(dateEdit.Text, out current))
            current = DateTime.Now;
        picker = new DatePickerDialog(dateEdit.Context, (sender, e) =>
        {
            if (tsc != null)
            {
                if (ct.IsCancellationRequested)
                {
                    tsc.SetCanceled();
                }
                else
                {
                    tsc.SetResult(e.Date);
                }
                tsc = null;
                picker.Dispose();
            }
        }, current.Year,current.Month-1,current.Day);
        picker.Show();
        return tsc.Task;
    }

    public static Task PickDateAndAssignAsync(this EditText dateEdit)
    {
        return dateEdit.PickDateAndAssignAsync(CancellationToken.None);
    }
    public static async Task PickDateAndAssignAsync(this EditText dateEdit, CancellationToken ct)
    {
        DateTime date = await dateEdit.PickDateAsync(ct);
        if (!ct.IsCancellationRequested)
        {
            dateEdit.Text = date.ToString("d");
        }
    }
}
Enjoy awesome asynchronous C#/.net support.

Running DevExtreme as MVC project in simulator

DevExtreme has a nice (web) simulator that lets you preview your application on a target device (tablet, phone, iOS, Android).

 

That’s really nice. However, out of the box, it works only when you have a special type of Visual Studio project that comes with DevExtreme (when you create a new DevExtreme project through one of its templates). Which might be a problem if you have other project type (i.e. MVC) instead – DevExtreme project is meant for distribution as a packaged “native” application. In that case no simulator for you, at least not out of the box.

Luckily here is a simple solution how to enable simulator for any web project. The mandatory step is to

  • find WebServer folder that is part of DevExtreme extension for Visual Studio. Mine is located in C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\mblaqgom.mw5.
  • from WebServer folder found in step above copy simulator.html and Images and Simulator folders to root of your MVC project.
  • Do not copy web.config – it will wreck your application

That’s it. You can run your application by going to URL/simulator.html?appPage=index.html (assuming your starting page is index.html). Note that you can pass other parameters to simulator as well, like device=iPhone and orientation=p..

If you want to omit the appPage=index.html parameter you can rename index.html to app.html and simulator will pick app.html by default.

Incoming TypeScript definitions for PhoneJS and ChartJS (DevExtreme)

PhoneJS along with ChartJS are DevExpress’ efforts in providing single page web applications for mobile platforms (think Tablets and Phones).  Together they are combined into DevExtreme combo. In practice they are pure javascript libraries without ties to any server side platform - which is good, are built with KnockoutJS, jQuery in mind, etc (really plenty of nice features, check hyperlinks). And they can be packed into “native” applications for various platforms using PhoneGap. Added bonus is an emulator (again in javascript) that let’s your preview applications. Everything you need to run projects based on DevExtreme is a web server. Any web server on any OS since they are client side stuff.

I recently poked around this technologies and I soon felt that one, rather important feature (well, to me at least) was missing. Typescript definition files were missing. Until now that is. They are coming with v13.2 and you can already preview them in beta. Plus, there is a template that let’s you start your project with Typescript code instead of Javascript. While this doesn’t seem a big deal, well, it is. Typescript is a huge boost for javascript development, more so when it comes to bigger projects. Hence it is a big deal to be able to use all of Typescript goodies with DevExtreme goodies. And now I can.

Other improvements are coming as well (improved theming, improved and new widgets, localization…). While I can’t call myself experienced in DevExtreme it will be definitely my first choice for new projects.

Solving Blend 2013 interactivity error

I am playing with Blend 2013 Silverlight Sketchflow for creating web application mockups. Recently I’ve stumbled into an curios error when adding interactivity to a button.

Here is the repro:

Create two screens, and a button on a screen. So far so good. Right click on that button and select Navigate To/Screen 2. Blend will add a navigational behavior, like:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Click">
        <pi:NavigateToScreenAction 
TargetScreen="SilverlightPrototype2Screens.Screen_1"/> </i:EventTrigger> </i:Interaction.Triggers>

It will underline pi:NavigateToScreenAction with a red squiggle as well complaining that type NavigateToScreenAction from assembly Microsoft.Expression.Prototyping.Interactivity is built with an older version of the Blend SDK, and it is not supported in Silverlight 5 projects.

A puzzling error. After playing around I discovered that the problem is with the referenced System.Windows.Interactivity assembly. Somehow Blend added a reference to a version 4.0.5.0. instead of 5.0.5.0.

Not sure what triggered the referencing of the wrong version but the solution is quite simple. Just remove it (in both projects) and reference the proper version. And Blend application sparks to life again.

Investigating why an instance is kept alive in a .net application

Sometimes, when I want to verify .net memory management behavior, I fire up ANTS Memory Profiler and run it on a test application just to see how memory management behaves.

So today I went and created this application

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B { Pointer = a };
        Console.WriteLine("One");
        Console.ReadLine();
        b.Pointer = null;
        b = null;
        Console.WriteLine("Two");
        Console.ReadLine();
        a = null;
        Console.WriteLine("Three");
        Console.ReadLine();
        a = new A();
        Console.WriteLine("Four");
        Console.ReadLine();
    }
}

class A
{

}

class B
{
    public A Pointer;
}

The ReadLine calls allow me to hit the “Take Memory Snapshot” in profiler. Later I examined these snapshots, specially the one between One and Two. What would you expect, how many instances are alive at that point? I’d say one, the instance of class A (referenced by a).

However, the profiler was showing, surprisingly, two. According to it, both an instance of A and an instance of B, were still very much alive. This result surprised me. Even more surprisingly, after Four there was still an instance of B around. How is this possible? There are no references to b and it is pointing to null. A bug in Memory Profiler? Hardly possible.

Right before I was going to post a question on RedGate’s forum I decided to check the IL code. With .net reflector of course. Immediately I saw the reason for that odd behavior. Can you spot it?

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 2
    .locals init (
        [0] class ConsoleApplication213.A a,
        [1] class ConsoleApplication213.B b,
        [2] class ConsoleApplication213.B b2)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication213.A::.ctor()
    L_0006: stloc.0 
    L_0007: newobj instance void ConsoleApplication213.B::.ctor()
    L_000c: stloc.2 
    L_000d: ldloc.2 
    L_000e: ldloc.0 
    L_000f: stfld class ConsoleApplication213.A ConsoleApplication213.B::Pointer
    L_0014: ldloc.2 
    L_0015: stloc.1 
    L_0016: ldstr "One"
    L_001b: call void [mscorlib]System.Console::WriteLine(string)
    L_0020: nop 
    L_0021: call string [mscorlib]System.Console::ReadLine()
    L_0026: pop 
    L_0027: ldloc.1 
    L_0028: ldnull 
    L_0029: stfld class ConsoleApplication213.A ConsoleApplication213.B::Pointer
    L_002e: ldnull 
    L_002f: stloc.1 
    L_0030: ldstr "Two"
    L_0035: call void [mscorlib]System.Console::WriteLine(string)
    L_003a: nop 
    L_003b: call string [mscorlib]System.Console::ReadLine()
    L_0040: pop 
    …
}

For some reason, compiler decided to allocate two references for class B: local variables b and b2. When the instance of class B is created it is stored in b2. After the Pointer property is assigned the same reference is stored to b while b2 isn’t set to null. Then when b is set to null, the b2 is still very much alive and thus keeping the instances count for class B to 1 – even though b is null and there are no other C# variables for referencing instances of B.

Mystery solved.  The lessons learned are that compiler might generate code one wouldn’t expect and that profiling memory isn’t always black and white. Those 50 shades of gray happen as well. IOW experience and good understanding of .net is a necessity.

When .net assemblies aren’t properly versioned odd errors happen

Today I’ve upgraded a SignalR library from 1.x to 2.0 in an MVC 5 (server) and WPF (client) projects I am developing. The upgrade itself went smooth but afterwards the client started yielding odd errors and refusing to connect anymore. It was yielding an exception saying something like Transport Connection time out (I can’t remember the exact message). Since it was a rather simple upgrade this error made no sense. Google didn’t help much either.

So I went debugging.

Investigation

First step is to create a simple repro sample – a solution with a basic server and a console client (see attached zip).

Second step is to turn on SignalR tracing on client:

hubConnection.TraceLevel = TraceLevels.All;
hubConnection.TraceWriter = Console.Out;

Armed with these two steps I was able to get an error that made a bit more sense although it was even more bizzare.

18:43:53.9073548 - null - ChangeState(Disconnected, Connecting)
18:43:55.4913444 - b8fd1874-483d-4d89-8a69-c2cfe33cf946 - WS Connecting to: ws://localhost:53705/signalr/connect?transport=webSockets&connectionToken=0dQ3scw2aJ7RbXuUsTfa4wlY%2FJlMzW%2FVL1sVb%2FyswewEO8n4qAth7Erpt0ga0laLV%2B8BCD833lZZy1MblOe0HuQs0O1mYi%2FfiiLSHc5%2F%2B1wk6tUsbFxMKVQFwRO9BvSW&connectionData=[{"Name":"formsHub"}] 18:43:55.5800651 - b8fd1874-483d-4d89-8a69-c2cfe33cf946 - WS: OnMessage({"C":"d-5AB67EA2-B,0|C,0|D,1|E,0","S":1,"M":[]})
18:43:55.5940751 - b8fd1874-483d-4d89-8a69-c2cfe33cf946 - OnError(System.MissingMethodException: Method not found: 'System.Collections.Generic.IEnumerator`1 Newtonsoft.Json.Linq.JArray.GetEnumerator()'. at Microsoft.AspNet.SignalR.Client.Transports.TransportHelper.ProcessResponse(IConnection connection, String response, Boolean& shouldReconnect, Boolean& disconnected, Action onInitialized) at Microsoft.AspNet.SignalR.Client.Transports.WebSocketTransport.OnMessage(String message) at Microsoft.AspNet.SignalR.WebSockets.WebSocketHandler.d__e.MoveNext())
18:43:55.6110864 - b8fd1874-483d-4d89-8a69-c2cfe33cf946 - WS: OnClose()

It says something like – I can’t find a method in the Newtonsoft.Json assembly. That’s totally weird as this kind of error should be handled at compile time.

I went looking into Newtonsoft.Json assembly referenced by SignalR 2.0. It correctly references version 5.0.8. The assembly in package folder has the method it was mentioned as missing. Mystery. One thing that caught my eye  while .net reflecting the assembly was its version. While the file version is 5.0.8. the assembly version is, oddly, 4.5.0.0. How come?

Fourth step was looking into modules loaded by my application. They are listed through Visual Studio-Debug/Windows/Modules. Amazingly, Visual Studio was listing Newtonsoft.Json v4.05.8.15203 from … GAC. Not from my package. And by looking at its date it was clear that it was an older version (4.8.2012). Heck, I didn’t even know it was in GAC. I didn’t put it, some other app had to.

 

From previous Googling I remembered an explanation somewhere that the missing GetEnumerator method was introduced in version 5.0.5. So this was probably it – .net was loading an older version from GAC - that was really missing that method. At this point I knew what was wrong.

Just in case, to make sure, I checked whether the assembly really was in GAC:

C:\Windows\system32>gacutil /l newtonsoft.json
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.18020
Copyright (c) Microsoft Corporation.  All rights reserved.

The Global Assembly Cache contains the following assemblies:
  newtonsoft.json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchi
tecture=MSIL

Number of items = 1

It was.

Remedy

The proper way would be to have a properly versioned Newtonsoft.Json assembly (those are strong key signed as well). That’s why there is versioning and .net wouldn’t make this confusion. I really wonder why James uses the same assembly version for assemblies that should really have different signatures. Hopefully he will fix this problem in next versions. But until then there is …

… the next best way is to force .net to not load it from GAC.  If the assembly is removed from GAC, .net won’t find the wrong version anymore. See, .net always tries GAC first and only if it doesn’t find a suitable assembly it will go looking elsewhere, like into the folder where your application is. Perhaps I could configure it to load the proper assembly through .config file but this solution is better – it’ll solve the problem unless an older newtonsoft.json is reinstalled again in GAC. Hm.

Removing assembly from GAC should be a rather simple process. Just fire

GACUTIL /U Newtonsoft.Json

and it should be removed. But not this time. Instead I got this warning:

C:\Windows\system32>gacutil /u newtonsoft.json
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.18020
Copyright (c) Microsoft Corporation.  All rights reserved.


Assembly: newtonsoft.json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, proces
sorArchitecture=MSIL
Unable to uninstall: assembly is required by one or more applications
Pending references:
              SCHEME: <WINDOWS_INSTALLER>  ID: <MSI>  DESCRIPTION : <Windows Installer>
Number of assemblies uninstalled = 0
Number of failures = 0

Basically it is saying that some installed application did install it into GAC and now it is preventing me from removing it from GAC. Uf, nasty. To make it worse, it doesn’t say which application. This article lists the way to “unreference it” to be able to remove it from GAC. Basically you have to remove its entry from the registry and then execute gacutil removal command again.

 

After registry modification it succeeded.

C:\Windows\system32>gacutil /u newtonsoft.json
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.18020
Copyright (c) Microsoft Corporation.  All rights reserved.


Assembly: newtonsoft.json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, proces
sorArchitecture=MSIL
Uninstalled: newtonsoft.json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, pro
cessorArchitecture=MSIL
Number of assemblies uninstalled = 1
Number of failures = 0

The aftermath

Removing that old Newtonsoft.Json from registry did the trick. SignalR works like charm again. However, I had to manually remove a component of an unidentified application. And this removal might cause problems with that application in the future.

I really hope that Newtonsoft.Json gets proper versioning to avoid situations like this. This should be a lesson to every library developer out there – do use proper version numbering!.

SignalRTest.zip (4.69 mb)

UPDATES:

12.11.2013: James, the author, is looking at the possible solution. See https://json.codeplex.com/discussions/465332#post1122165.