NullReferenceException during deserialization

Oct 14, 2010 at 6:00 PM

I'm using Json.NET (35r8) in a Windows Phone app, and we sometimes see one of two NullReferenceExceptions at startup. When we launch the app, we download some data from a web API and try to deserialize it. We haven't been able to nail down the exact conditions that cause it, but about 10-20% of the time we'll see one of two possible errors.

The first happens in JsonSerializerInternalReader.GetContractSafe(Type type), in the return statement. I've run the app in debug mode, with Json.NET included as a project reference, and I can see that it's the ContractResolver that's coming back as null in certain cases. I can also tell that every time it happens, we've just set the backing field _contractResolver by getting it from DefaultContractResolver.Instance. Also, the setter for the ContractResolver property is never called, so it seems that somehow DefaultContractResolver.Instance is returning null (which doesn't make much sense, since it's a readonly property and should always be initialized).

The second error occurs in DefaultContractResolver.GetDefaultCreator(Type createdType). In this case, ReflectionDelegateFactory is coming back null. Again, that doesn't seem to make much sense, but that's what seems to be happening.

Does anyone have any idea why this is happening, or how we can prevent these errors? If there's any other information I can provide, I'm glad to help.

Coordinator
Oct 14, 2010 at 8:43 PM

I don't know. It works on every other platform.

Is this occurring in the emulator or the phone itself?

Oct 14, 2010 at 8:49 PM

Now that you mention it, it seems to happen more often in the emulator. I'm not sure if I've seen it on the phone or not. I'll keep an eye on that and let you know if I see it more often on one or the other.

Nov 4, 2010 at 3:47 PM

Sorry for the late response. We put this issue on the back burner for a while, but we're now taking another look at it.

I can confirm that this happens on the phone as well, possibly even more often. We were intially referencing the Silverlight assembly that came in the release, but we're now using a project reference that builds Json.NET as a Windows Phone class library, just in case there were any subtle differences in the frameworks. Unfortunately, we're still seeing the error even with that change.

I don't know if any of that helps at all, but I thought I'd post the information just in case it does.

Mar 12, 2011 at 8:38 AM
Edited Mar 12, 2011 at 8:55 AM

I can confirm this problem. It's sporadic and there is no pattern to it really. I get it ON THE SAME DATA also (i.e. the exact same json string), which is weird :)

Upon further investigation it looks like the exception has an inner NotSupportedException

Stack trace:

   at System.RuntimeType.get_GUID()
   at Newtonsoft.Json.Serialization.DefaultContractResolver.GetDefaultCreator(Type createdType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.InitializeContract(JsonContract contract)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateArrayContract(Type objectType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.CreateContract(Type objectType)
   at Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(Type type)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.GetContractSafe(Type type)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, Type t, JsonConverter propertyConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize[T](JsonReader reader)
   at GamesRadar.Features.News.NewsListViewModel.<LoadDataFromSavedState>b__e()
   at Microsoft.Phone.Reactive.Observable.<>c__DisplayClass82`1.<>c__DisplayClass84.<ToAsync>b__81()
   at Microsoft.Phone.Reactive.ThreadPoolScheduler.<>c__DisplayClass1.<Schedule>b__0(Object _)
   at System.Threading.ThreadPool.WorkItem.doWork(Object o)
   at System.Threading.Timer.ring()

Jun 23, 2011 at 5:14 PM

Did anyone get to the bottom of this? I too get it at seemingly random intervals on both the Emulator and the Phone

Sep 30, 2011 at 8:16 PM

I found a solution to the problem. Apparently on WP you need to use proper singleton lazy initialization pattern.  I.e. I had to change:

Instance implementation in DefaultContractResolver
  /// <summary>
  /// Used by <see cref="JsonSerializer"/> to resolves a <see cref="JsonContract"/> for a given <see cref="Type"/>.
  /// </summary>
  public class DefaultContractResolver : IContractResolver
  {
    private static readonly IContractResolver _instance = new DefaultContractResolver(true);
...
    public static IContractResolver Instance
    {
        get { return _instance; }
    }

And

  internal sealed class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory
  {
    public static readonly LateBoundReflectionDelegateFactory _instance = new LateBoundReflectionDelegateFactory();

    public static ReflectionDelegateFactory Instance
    {
        get { return _instance; }
    }

I don't have a repro of this problem anymore.

Coordinator
Oct 1, 2011 at 9:30 AM

Done