EDIT: It is not related to the try/catch return null statement. I have debugged it and watched it and ensured it does not go to that catch block. I even commented it out, to no avail.
I am tiring to build a configuration manager for my application. Essentially I have certain variables that need to be stored in a JSON file and read during application startup so that certain values are known.
For some of these config variables, I'll allow the user to override the default, so if the "user" key has a non-empty string, I'll use that. If there is no user key or if there is an empty string, I'll use the default. To satisfy this requirement I wrote "AllowUserConfig" and "CoalesceUserDefault" methods to take care of that.
At this point, I have a JSON file (below). I copied the data and pasted into visual studio as a class, JSONConfig. I then have a ConfigManager file that does the real work and my program.cs calls the ConfigManager to use the DeserializeConfigVariables method to read the config file (which is in the correct location), and create a JSONConfig object from that.
With that being said, the JSONConfig object in DeserializeConfigVariables is being returned as null (on the line that says configVariables = serializer.Deserialize<JSONConfig>(jsonReader);).  Is there something I'm missing.  I've gone over everything a hundred times and can't see what I'm doing incorrectly.
Any and all help would be appreciated.
This is my JSON:
{
  "format": {
     "date": {
        "default": "yyyyMMdd",
        "user": ""
     },
     "month_year": {
        "default": "MM_YYYY",
        "user": ""
     }
  },
  "placeholders": {
     "current_date": "{date}",
     "month_year": "{month_year}",
     "last_monday": "{prev_monday}",
     "next_monday": "{next_monday}"
  },
  "resource_locations": {
     "directories": {
        "root_working": {
           "default": "C:\\ALL",
           "user": ""
        },
        "exports": {
           "default": "C:\\ALL\\Exports",
           "user": ""
        },
        "completed_exports": {
           "default": "C:\\ALL\\Done",
           "user": ""
        },
        "archived": {
           "default": "C:\\ALL\\Archives",
           "user": ""
        }
     },
     "compression": {
        "filename": {
           "default": "{next_monday}_daily_{date}.zip",
           "user": ""
        }
     },
     "logging": {
        "directory": "logs",
        "process_filename": "activity_log_{month_year}.log",
        "process_error_filename": "errors.log",
        "system_error_filename": "sys_errors.log"
     }
  }
}
And this is the JSONConfig class I made by copying and pasting JSON as class in Visual Studio:
using System;
using Newtonsoft.Json;
namespace Config
{
   public class JSONConfig
   {
       public RootObject ConfigVariables { get; set; }
   }
   public class RootObject
   {
       public Format format { get; set; }
       public Placeholders placeholders { get; set; }
       public Resource_Locations resource_locations { get; set; }
   }
   public class Format
   {
       public Date date { get; set; }
       public Month_Year month_year { get; set; }
   }
   public class Date
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Month_Year
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Placeholders
   {
       public string current_date { get; set; }
       public string month_year { get; set; }
       public string last_monday { get; set; }
       public string next_monday { get; set; }
   }
   public class Resource_Locations
   {
       public Directories directories { get; set; }
       public Compression compression { get; set; }
       public Logging logging { get; set; }
   }
   public class Directories
   {
       public Root_Working root_working { get; set; }
       public Exports exports { get; set; }
       public Completed_Exports completed_exports { get; set; }
       public Archived archived { get; set; }
   }
   public class Root_Working
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Exports
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Completed_Exports
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Archived
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Compression
   {
       public Filename filename { get; set; }
   }
   public class Filename
   {
       public string _default { get; set; }
       public string user { get; set; }
   }
   public class Logging
   {
       public string directory { get; set; }
       public string process_filename { get; set; }
       public string process_error_filename { get; set; }
       public string system_error_filename { get; set; }
   }
}
Then, in my ConfigManager files I have the following:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
using Newtonsoft.Json;
namespace Config
{
   static class ConfigManager
   {
       // Assumes parent directory is bin.  Assumes config is sibling to bin.
       private static string _initialConfig = @"config\config.json";
       public static string ConfigPath() => Path.Combine(GetRootAppDir(), _initialConfig);
       public static string Parent(string directory)
       {
           string parentDirectory = Directory.GetParent(directory).FullName;
           return parentDirectory;
       }
       public static string GetRootAppDir()
       {
           return Parent(Parent(Directory.GetCurrentDirectory()));
       }
       public static JSONConfig DeserializeConfigVariables()
       {
           try
           {
               var configVariables = new JSONConfig();
               var serializer = new JsonSerializer();
               Console.WriteLine($"Config Path: {ConfigPath()}"); //testing
               using (var reader = new StreamReader(ConfigPath()))
               using (var jsonReader = new JsonTextReader(reader))
               {
                   configVariables = serializer.Deserialize<JSONConfig>(jsonReader);
               }
               return configVariables;
           }
           catch (System.IO.DirectoryNotFoundException ex)
           {
               Console.WriteLine(ex.Message);
               return null;
           }
       }
       public static bool AllowUserConfig(object configVariable)
       {
           string userFieldName = "user";
           var objType = configVariable.GetType();
           return objType.GetMethod(userFieldName) != null;
       }
       public static string CoalesceUserDefault(dynamic configVariable)
       {
           if (AllowUserConfig(configVariable))
           {
               if (!(String.IsNullOrEmpty(configVariable.user)))
               {
                   return configVariable.user;
               }
           }
           return configVariable._default;
       }
   }
}


