Resolved Facing an issue including Dictionary method in Json class

Palak Shah

Well-known member
Joined
Apr 29, 2020
Messages
97
Programming Experience
1-3
I had JSON string which I converted to JSON Class, and now I want to add Dictionary method insode my JSON class which will return me certain values from JSON class variables

And for that I am facing an issue including Dictionary method in Json class c#

Can someone help where can I include that method?

My JSON Class Model:
namespace JsonModel
{
    using Newtonsoft.Json;
    using System.Collections.Generic;

    public partial class StringResourcesX
    {
        [JsonProperty("StringResources")]
        public StringResources StringResources { get; set; }
    }

    public partial class StringResources
    {
        
        [JsonProperty("Culture")]
        public Culture Culture { get; set; }

        public Culture_ Culture_ { get; set; }
        public FullName FullName { get; set; }

        public Dictionary<Culture_, FullName> CulturalNames { get; set; }
    }
    
    

    public partial class Culture
    {
        [JsonProperty("Cultures")]
        public Cultures Cultures { get; set; }

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

    public partial class CulturalName
    {
        [JsonProperty("AE")]
        public AE AE { get; set; }

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

        
    }

    public partial class AE
    {
        [JsonProperty("AE_Name")]
        public string AE_Name { get; set; }

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

    
    public partial class GB
    {
        [JsonProperty("GB_Name")]
        public string GB_Name { get; set; }

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

    public partial class Cultures
    {
        [JsonProperty("Culture_UK")]
        public string Culture_UK { get; set; }

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

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

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

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

    public enum Culture_
    {
        GB,
        US,
        IT,
        FR,
        CA,
        DE,
        SE,
        NL,
        NZ,
        AU,
        AE,
        CN,
        JP,
        IE,
        IN,
        ES
    }

    public class FullName
    {
        public string First;
        public string Last;
        public FullName(string first, string last)
        {
            this.First = first;
            this.Last = last;
        }
    }
}


Method Which I want to include in class model:
public static Dictionary<Culture_, FullName> CulturalNames = new Dictionary<Culture_, FullName>
        {
            {Culture_.GB, new FullName(Culture.CulturalName.GB.GB_Name, Culture.CulturalName.GB.GB_LastName)},{Culture_.AE, new FullName(Culture.CulturalName.AE.AE_Name, Culture.CulturalName.AE.AE_LastName)}
        };

But I'm getting compile time error as " a field initializer cannot reference the nonstatic field ", so I'm not able to understandhow and where should I include my method which will work
 
Yes

basically I want to serialise Dictionary maybe like these, and my code is bit complex, where I have few data seaprately "Name" and "Lastname" as per cultures and then I want to add them in dictionary

Now after deserialization, to access dictionary value I have to use singleton so instead of that If i can serialize that dictionary field in json it self so it can be accessed directly

But i'm not able to figure out how do I do that


JSON Class:
namespace Framework.JsonModel
{
    using Framework.Config;
    using Framework.Helpers;
    using Newtonsoft.Json;
    using System.Collections.Generic;
    using System.ComponentModel;

    public class StringResourcesTestData
    {
        public const string jsonFilePath = "JsonData\\Constants\\StringResources.json";
        public static StringResourcesX StringResources { get; set; }

        private StringResourcesTestData()
        {

        }

        public static StringResourcesX Get()
        {
            if(StringResources == null)
                StringResources = JsonHelper
                    .GetTestParams<StringResourcesJson>(ConfigProvider.BuildPath(jsonFilePath))
                    .StringResources;

            return StringResources;
        }
    }

    public partial class StringResourcesJson
    {
        [JsonProperty("StringResources")]
        public StringResourcesX StringResources { get; set; }
    }

    public partial class StringResourcesX
    {
        [JsonProperty("Culture")]
        public Culture Culture { get; set; }

    
    }

  

    public partial class Culture
    {
        [JsonProperty("Cultures")]
        public Cultures Cultures { get; set; }

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

    public partial class CulturalName
    {
        public enum CultureEnum
        {
            GB,
            US,
            IT,
            FR,
            CA,
            DE,
            SE,
            NL,
            NZ,
            AU,
            AE,
            CN,
            JP,
            IE,
            IN,
            ES
        }
        public class FullName
        {
            public string First;
            public string Last;
            public FullName(string first, string last)
            {
                this.First = first;
                this.Last = last;
            }
        }
        public Dictionary<CultureEnum, FullName> CulturalNames;

        public FullName GetName(CultureEnum culture_)
        {
            if (CulturalNames == null)
            {
                CulturalNames = new Dictionary<CultureEnum, FullName>
                {
                    {CultureEnum.GB, new FullName (GB.Name, GB.LastName)},{CultureEnum.US, new FullName(US.Name ,US.LastName)},
                    {CultureEnum.IT, new FullName(IT.Name, IT.LastName)},{CultureEnum.ES, new FullName(ES.Name, ES.LastName)},
                    {CultureEnum.FR, new FullName(FR.Name, FR.LastName)},{CultureEnum.AE, new FullName(AE.Name, AE.LastName)},
                    {CultureEnum.DE, new FullName(DE.Name, DE.LastName)},{CultureEnum.NL, new FullName(NL.Name, NL.LastName)},
                    {CultureEnum.JP, new FullName(JP.Name, JP.LastName)},{CultureEnum.SE, new FullName(SE.Name, SE.LastName)},
                    {CultureEnum.IE, new FullName(IE.Name, IE.LastName)},{CultureEnum.AU, new FullName(AU.Name, AU.LastName)},
                    {CultureEnum.CA, new FullName(CA.Name, CA.LastName)},{CultureEnum.NZ, new FullName(NZ.Name, NZ.LastName)},
                    {CultureEnum.IN, new FullName(IN.Name, IN.LastName)},{CultureEnum.CN, new FullName(CN.Name, CN.LastName)}
                };
            }

            return CulturalNames[culture_];
        }


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    public partial class Cultures
    {
        [JsonProperty("Culture_UK")]
        public string Culture_UK { get; set; }

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

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

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

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

}


JSON Data:
{
  "StringResources": {
    "Culture": {
      "Cultures": {
        "Culture_UK": "en-GB",
        "Culture_US": "en-US",
        "Culture_CA": "en-CA",
        "Culture_DE": "de-DE",
        "Culture_JP": "ja-JP"
      },
      "CulturalName": {
        "AE": {
          "Name": "Abu'l-Fadl",
          "LastName": "Isa"
        },
        "GB": {
          "Name": "Jamie",
          "LastName": "Lanister"
        },
        "US": {
          "Name": "Tyrion",
          "LastName": "Lanister"
        },
        "CN": {
          "Name": "陶",
          "LastName": "致远"
        },
        "IT": {
          "Name": "Clelia",
          "LastName": "Calabrese"
        },
        "ES": {
          "Name": "Sebastián",
          "LastName": "Hinojosa Argüello"
        },
        "FR": {
          "Name": "L'Heureux",
          "LastName": "Boulé"
        },
        "DE": {
          "Name": "Jörg",
          "LastName": "Gärtner"
        },
        "NL": {
          "Name": "Selma",
          "LastName": "Løkkeberg"
        },
        "SE": {
          "Name": "Ekström",
          "LastName": "Åberg"
        },
        "IE": {
          "Name": "Bailey",
          "LastName": "Quinn"
        },
        "AU": {
          "Name": "Lola",
          "LastName": "Patel"
        },
        "CA": {
          "Name": "Max",
          "LastName": "Godfrey"
        },
        "NZ": {
          "Name": "Edward",
          "LastName": "Bevan"
        },
        "IN": {
          "Name": "Anshu",
          "LastName": "Chahal"
        },
        "JP": {
          "Name": "ナルト",
          "LastName": "うずまき"
        }
      }
    }
  }
}

And this is how I currently access


C#:
var StringResourceData = StringResourcesTestData.Get();
            var t1 = StringResourcesTestData.Get().Culture.CulturalName.GetName(Constants.Culture.GB);
            var t2 = StringResourcesTestData.Get().Culture.CulturalName.GetName(Constants.Culture.AE);
@Skydiver - Any suggestion on my code?, where I can implement Dictionary and include it in Json?
 
Apparently, there is no need to explictly use the StringEnumConverter. Json.NET will take care of things.

In general, I've learned to stay away from singletons if at all possible, but you really must use one, below is one way to set one up.

C#:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;

public enum CultureEnum
{
    GB,
    US,
    IT,
    FR,
    CA,
    DE,
    SE,
    NL,
    NZ,
    AU,
    AE,
    CN,
    JP,
    IE,
    IN,
    ES,
}

class FullName
{
    public string Name { get; set; }
    public string LastName { get; set; }

    public override string ToString() => $"{Name} {LastName}";
}

class Culture
{
    public IDictionary<string, string> Cultures { get; set; }
    public IDictionary<CultureEnum, FullName> CulturalName { get; set; }
}

class StringResources
{
    public Culture Culture { get; set; }

    public static StringResources Singleton { get; } = Load(@"StringResources3.json");

    public static StringResources Load(string jsonFile)
    {
        var jsonString = File.ReadAllText(jsonFile);
        var jobject = JObject.Parse(jsonString);
        return jobject["StringResources"].ToObject<StringResources>();
    }
}

class Program
{
    static void Main()
    {
        Console.WriteLine(StringResources.Singleton.Culture.CulturalName[CultureEnum.DE]);
        Console.WriteLine(StringResources.Singleton.Culture.Cultures["Culture_DE"]);
    }
}

This is using the same JSON data that you have in your post above.
StringResources3.json:
{
  "StringResources": {
    "Culture": {
      "Cultures": {
        "Culture_UK": "en-GB",
        "Culture_US": "en-US",
        "Culture_CA": "en-CA",
        "Culture_DE": "de-DE",
        "Culture_JP": "ja-JP"
      },
      "CulturalName": {
        "AE": {
          "Name": "Abu'l-Fadl",
          "LastName": "Isa"
        },
        "GB": {
          "Name": "Jamie",
          "LastName": "Lanister"
        },
        "US": {
          "Name": "Tyrion",
          "LastName": "Lanister"
        },
        "CN": {
          "Name": "陶",
          "LastName": "致远"
        },
        "IT": {
          "Name": "Clelia",
          "LastName": "Calabrese"
        },
        "ES": {
          "Name": "Sebastián",
          "LastName": "Hinojosa Argüello"
        },
        "FR": {
          "Name": "L'Heureux",
          "LastName": "Boulé"
        },
        "DE": {
          "Name": "Jörg",
          "LastName": "Gärtner"
        },
        "NL": {
          "Name": "Selma",
          "LastName": "Løkkeberg"
        },
        "SE": {
          "Name": "Ekström",
          "LastName": "Åberg"
        },
        "IE": {
          "Name": "Bailey",
          "LastName": "Quinn"
        },
        "AU": {
          "Name": "Lola",
          "LastName": "Patel"
        },
        "CA": {
          "Name": "Max",
          "LastName": "Godfrey"
        },
        "NZ": {
          "Name": "Edward",
          "LastName": "Bevan"
        },
        "IN": {
          "Name": "Anshu",
          "LastName": "Chahal"
        },
        "JP": {
          "Name": "ナルト",
          "LastName": "うずまき"
        }
      }
    }
  }
}
 
Last edited:
The code above is fragile because the dictionary keys in theCulturalNames are dependent on the hardcoded CultureEnum. The following reads the JSON file at compile time and generates the enum, as well as the dictionaries. There is no need for the JSON file to exist at runtime.
StringResources.tt:
<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="Newtonsoft.Json" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="Newtonsoft.Json.Linq" #>
<#@ output extension=".cs" #>
<#
    var jsonFile = this.Host.ResolvePath("StringResources3.json");
    var jsonString = File.ReadAllText(jsonFile);
    var jobject = JObject.Parse(jsonString);
    var cultures = jobject["StringResources"]["Culture"]["Cultures"].ToObject<Dictionary<string,string>>();
    var dictionary = jobject["StringResources"]["Culture"]["CulturalName"].ToObject<Dictionary<string,JToken>>();
#>

using System.Collections.Generic;

enum CultureEnum
{
<#
    PushIndent("    ");
    foreach(var key in dictionary.Keys)
        WriteLine($"{key},");
    PopIndent();
#>
}

class FullName
{
    public string Name { get; set; }
    public string LastName { get; set; }

    public override string ToString() => $"{Name} {LastName}";
}

class Culture
{
    public readonly IReadOnlyDictionary<string, string> Cultures = new Dictionary<string, string>()
    {
<#
    foreach(var kvp in cultures)
    {
#>
        ["<#= kvp.Key #>"] = "<#= kvp.Value #>",
<#
    }
#>
    };

    public readonly IReadOnlyDictionary<CultureEnum, FullName> CulturalName = new Dictionary<CultureEnum, FullName>()
    {
<#
    foreach(var kvp in dictionary)
    {
        string name = kvp.Value["Name"].ToString();
        string lastName = kvp.Value["LastName"].ToString();
#>
        [CultureEnum.<#= kvp.Key #>] = new FullName() { Name = "<#= name #>", LastName = "<#= lastName #>" },
<#
    }
#>
    };
}

static class StringResources
{
    public static Culture Culture { get; } = new Culture();
}

which generates the following code:
StringResources.cs:
using System.Collections.Generic;

enum CultureEnum
{
    AE,
    GB,
    US,
    CN,
    IT,
    ES,
    FR,
    DE,
    NL,
    SE,
    IE,
    AU,
    CA,
    NZ,
    IN,
    JP,
}

class FullName
{
    public string Name { get; set; }
    public string LastName { get; set; }

    public override string ToString() => $"{Name} {LastName}";
}

class Culture
{
    public readonly IReadOnlyDictionary<string, string> Cultures = new Dictionary<string, string>()
    {
        ["Culture_UK"] = "en-GB",
        ["Culture_US"] = "en-US",
        ["Culture_CA"] = "en-CA",
        ["Culture_DE"] = "de-DE",
        ["Culture_JP"] = "ja-JP",
    };

    public readonly IReadOnlyDictionary<CultureEnum, FullName> CulturalName = new Dictionary<CultureEnum, FullName>()
    {
        [CultureEnum.AE] = new FullName() { Name = "Abu'l-Fadl", LastName = "Isa" },
        [CultureEnum.GB] = new FullName() { Name = "Jamie", LastName = "Lanister" },
        [CultureEnum.US] = new FullName() { Name = "Tyrion", LastName = "Lanister" },
        [CultureEnum.CN] = new FullName() { Name = "陶", LastName = "致远" },
        [CultureEnum.IT] = new FullName() { Name = "Clelia", LastName = "Calabrese" },
        [CultureEnum.ES] = new FullName() { Name = "Sebastián", LastName = "Hinojosa Argüello" },
        [CultureEnum.FR] = new FullName() { Name = "L'Heureux", LastName = "Boulé" },
        [CultureEnum.DE] = new FullName() { Name = "Jörg", LastName = "Gärtner" },
        [CultureEnum.NL] = new FullName() { Name = "Selma", LastName = "Løkkeberg" },
        [CultureEnum.SE] = new FullName() { Name = "Ekström", LastName = "Åberg" },
        [CultureEnum.IE] = new FullName() { Name = "Bailey", LastName = "Quinn" },
        [CultureEnum.AU] = new FullName() { Name = "Lola", LastName = "Patel" },
        [CultureEnum.CA] = new FullName() { Name = "Max", LastName = "Godfrey" },
        [CultureEnum.NZ] = new FullName() { Name = "Edward", LastName = "Bevan" },
        [CultureEnum.IN] = new FullName() { Name = "Anshu", LastName = "Chahal" },
        [CultureEnum.JP] = new FullName() { Name = "ナルト", LastName = "うずまき" },
    };
}

static class StringResources
{
    public static Culture Culture { get; } = new Culture();
}

and can be called with:
Program.cs:
class Program
{
    static void Main()
    {
        Console.WriteLine(StringResources.Culture.CulturalName[CultureEnum.DE]);
        Console.WriteLine(StringResources.Culture.Cultures["Culture_DE"]);
    }
}

This uses the same "StringResources3.json", that I've been using previously.
 
Back
Top Bottom