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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.