2

I am trying to deserialize below json

  {
   "Settings": {
   "ServiceUrl": "http://www.somethingsample.sample",
   "FrequencyOfSchedulerInMinutes": 6    
  },

 "ApplicationLog": {
   "Serilog": {
      "MinimumLevel": "Information",
      "WriteTo": [
       {
        "Name": "RollingFile",
        "Args": {
           "pathFormat": "%PROGRAMDATALog.txt",
           "fileSizeLimitBytes": 10485760,
           "retainedFileCountLimit": 10,
           "rollingInterval": "Day",
           "outputTemplate": "== {Timestamp:yy}{Exception}"
       }
     }
    ]
   }
  }   
}

The c# classes are

  public class Settings
  {
      [JsonProperty("ServiceUrl")]
      public string ServiceUrl { get; set; }

      [JsonProperty("FrequencyOfSchedulerInMinutes")]
      public int FrequencyOfSchedulerInMinutes { get; set; }

  }

  public class Args
  {
      [JsonProperty("pathFormat")]
      public string pathFormat { get; set; }

      [JsonProperty("fileSizeLimitBytes")]
      public int fileSizeLimitBytes { get; set; }

      [JsonProperty("retainedFileCountLimit")]
      public int retainedFileCountLimit { get; set; }

      [JsonProperty("rollingInterval")]
      public string rollingInterval { get; set; }

      [JsonProperty("outputTemplate")]
      public string outputTemplate { get; set; }
   }

   public class WriteTo
   {
      [JsonProperty("Name")]
      public string Name { get; set; }

      [JsonProperty("Args")]
      public Args Args { get; set; }
   }

   public class Serilog
   {
       [JsonProperty("MinimumLevel ")]
       public string MinimumLevel { get; set; }

       [JsonProperty("WriteTo")]
       public List<Dictionary<WriteTo, object>> WriteTo { get; set; }

   }

  public class ApplicationLog
  {
       [JsonProperty("Serilog")]
       public Serilog Serilog { get; set; }
  }

  public class RootObject
  {
      public Settings Settings { get; set; }
      public ApplicationLog ApplicationLog { get; set; }
  }

Here is my Resolver

  class DictionaryAsArrayResolver : DefaultContractResolver
  {
    protected override JsonContract CreateContract(Type objectType)
    {
        if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) ||
                                                (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>))))
        {
            return base.CreateArrayContract(objectType);
        }

        return base.CreateContract(objectType);
     }
  }

This is how I do deserialization

  JsonSerializerSettings settings = new JsonSerializerSettings();
  settings.ContractResolver = new DictionaryAsArrayResolver();

   var objectValue = JsonConvert.DeserializeObject<Dictionary<string, object>>(json, settings);
   var items = JsonConvert.DeserializeObject<RootObject>(objectValue.Values.First().ToString(), settings);

I am getting below error

Run-time exception (line 39): Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'Settings', line 2, position 13.

{"Could not convert string 'Name' to dictionary key type 'MyProject.WriteTo'. Create a TypeConverter to convert from the string to the key type object. Path 'ApplicationLog.Serilog.WriteTo[0].Name', line 21, position 17."}

kudlatiger
  • 3,028
  • 8
  • 48
  • 98
  • Possible duplicate of [Json.net deserialized nested Dictionary](https://stackoverflow.com/questions/21394377/json-net-deserialized-nested-dictionary) – Lorenzo Isidori Aug 07 '19 at 06:47
  • There's no type `AppSettings` shown in your question, so `JsonConvert.DeserializeObject(objectValue.Values.First().ToString(), settings);` does not compile. Can you share a [mcve]? Also, what part of the JSON is `(objectValue.Values.First().ToString()` supposed to refer to? – dbc Aug 07 '19 at 06:48
  • @dbc sorry it was typo. updated question. – kudlatiger Aug 07 '19 at 07:36
  • @dbc reproduced here https://dotnetfiddle.net/1TLT4L – kudlatiger Aug 07 '19 at 07:58

1 Answers1

1

Seems a bit strange to have object WriteTo as a dictionary key. But when changing Serilog to:

public class Serilog
{
    [JsonProperty("MinimumLevel ")]
    public string MinimumLevel { get; set; }

    [JsonProperty("WriteTo")]
    public List<WriteTo> WriteTo { get; set; }
}

It's possible to deserialize it without the ContractResolver.

var rootObject = JsonConvert.DeserializeObject<RootObject>(json);
Torbjörn Hansson
  • 18,354
  • 5
  • 33
  • 42