3

I have a JSON that I'd like to DeserializeObject into an outerDictionary with innerDictionary and innermostClass as so:

var entityMap = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, fieldClass>>>(File.ReadAllText("map.json"));

However, the innerDictionary may have a string:string instead of string:innerMostClass.

{
"Client": {
    "__class__": "contact",

    "ClientId": {
        "__field__": "new_ndisclientid",
        "__type__": "string"
    },
    "GivenName": {
        "__field__": "firstname",
        "__type__": "string"
    },
},
"Case": {
    "__class__": "contact",

    "CaseId": {
        "__field__": "new_ndiscaseid",
        "__type__": "string"
    }
}
}

Is there a way to do this? I don't want to make all of it into Classes.

Is it possible to do this with a custom JsonConverter?

EDIT: Renamed classname to entityName for clarity. ClientId and GivenName would be deserialized into fieldClasses.

2 Answers 2

4

You can use dynamic or object instead of inner class

    var json =
        "{\r\n\t\"Client\": {\r\n\t\t\"__entityName__\": \"contact\",\r\n\r\n\t\t\"ClientId\": {\r\n\t\t\t\"__field__\": \"new_ndisclientid\",\r\n\t\t\t\"__type__\": \"string\"\r\n\t\t},\r\n\t\t\"GivenName\": {\r\n\t\t\t\"__field__\": \"firstname\",\r\n\t\t\t\"__type__\": \"string\"\r\n\t\t}\r\n\t}\r\n}";
    var deserialized = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, dynamic>>>(json);
List<object> values = deserialized.SelectMany(result => result.Value).Cast<object>().ToList();

If you want separate inner class

public class Client
{
    public string __entityName__ { get; set; }
    public Dictionary<string, string> ClientId { get; set; }
    public Dictionary<string, string> GivenName { get; set; }
}
var deserializedWithClass = JsonConvert.DeserializeObject<Dictionary<string, Client>>(json);
Sign up to request clarification or add additional context in comments.

3 Comments

I've tried dynamic but would prefer it to be a class or something similar, if possible. I want the class to have methods and the dynamic data type does not have IntelliSense in Visual Studio.
Updated answer with class instead of dynamic
Making the root into a Class is another way. But I think it has to be a Dictionary/List as the root may not always be a Client. It may be say, a Case which has different inner Classes, but they have the same fields. I've updated the original post JSON to show what I mean.
1

Deserialize nested JSON into Class. not on dictionary based but it's useful.

Step 01: open the link https://jsonformatter.org/json-parser

Step 02: copy the down contents.

{
"Client": {
    "__class__": "contact",

    "ClientId": {
        "__field__": "new_ndisclientid",
        "__type__": "string"
    },
    "GivenName": {
        "__field__": "firstname",
        "__type__": "string"
    }
},
"Case": {
    "__class__": "contact",

    "CaseId": {
        "__field__": "new_ndiscaseid",
        "__type__": "string"
    }
}
}

Step 03: Open above link. copy contents and past in to left side and click on to JSON Parser button. Look like below image.enter image description here

Step 04: Click on download button. Downloading the jsonformatter.txt file. Successfully download the file as jsonformatter.txt.

Step 05: Copy step 02 content and open url https://json2csharp.com/.Copy contents and past in to left side and click on to Convert button. Look like below image.enter image description here

Step 06: In Scripting.

(A) Create myRootClass.cs file and copy and past down contents to your file.[[System.Serializable] it's used in unity 3d software c# scripting]

[System.Serializable]
public class myRootClass
{
    [System.Serializable]
    public class ClientId
    {
        public string __field__ { get; set; }
        public string __type__ { get; set; }
    }
    [System.Serializable]
    public class GivenName
    {
        public string __field__ { get; set; }
        public string __type__ { get; set; }
    }
    [System.Serializable]
    public class Client
    {
        public string __class__ { get; set; }
        public ClientId ClientId { get; set; }
        public GivenName GivenName { get; set; }
    }
    [System.Serializable]
    public class CaseId
    {
        public string __field__ { get; set; }
        public string __type__ { get; set; }
    }
    [System.Serializable]
    public class Case
    {
        public string __class__ { get; set; }
        public CaseId CaseId { get; set; }
    }
    [System.Serializable]
    public class Root
    {
        public Client Client { get; set; }
        public Case Case { get; set; }
    }
}

    

(B) Read the jsonformatter.txt file.

// Read entire text file content in one string 
    string  textFilePath = "C:/Users/XXX/Downloads/jsonformatter.txt";//change path
    string jsontext = System.IO.File.ReadAllText(textFilePath);  
    Debug.Log("Read Json"+jsontext);// used Console.Writeline

(C) Convert string into C# and show the data.

  Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(jsontext); 
  var client = myDeserializedClass.Client;
  Debug.Log("client.__class__ :- "+client.__class__); //used Console.Writeline
  Debug.Log("client.ClientId.__field__ :- "+client.ClientId.__field__);// used Console.Writeline
  Debug.Log("client.GivenName.__field__ :- "+client.GivenName.__field__);// used Console.Writeline

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.