-1

I have a JSON object and one property of this JSON is a dictionary that can receive a string value or an array of string values.

My question is: is it possible to deal with this case using a dictionary with a conditional generic parameter, example: Dictionary<string, string || string[]>?

Because i need to deserialize the values in one dictionary.

Following bellow a example of JSON object, where clientContent needs to map to such a dictionary:

"clientConfDesc": {
   "clientContent": {
       "app.log.mail.port": "",
       "app.log.mail.protocol": "",
       "app.log.mail.receiver": "",
       "app.log.mail.server": "",
       "app.lookupDaemon.interval": "",
       "app.lookupDaemon.use": "yes",
       "app.remoteCall.ttl": "",
       "app.typeDef": ["5, , PD, PEDIDO"]
   }
}

Note: I know that the object of this example JSON is a class, but the properties of this class are variable, that is, I cannot map them because a property may cease to exist or new properties may be added, this is why I treat it this case as a dictionary because I want to delete or add parameters later in this class.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • Does this answer your question? [How can I access and process nested objects, arrays or JSON?](https://stackoverflow.com/questions/11922383/how-can-i-access-and-process-nested-objects-arrays-or-json) – Liam Feb 12 '21 at 15:41
  • Would you be happy if even the single values were available in an array? So you could use `Dictionary`? – DavidG Feb 12 '21 at 15:41
  • Also, are you sure that last line in your JSON is correct? Is it meant to be a single string inside an array? – DavidG Feb 12 '21 at 16:10
  • c# doesn't really have nice supported for union types like the f# [discriminated union](https://fsharpforfunandprofit.com/posts/discriminated-unions/). In c# it's going to be easiest to deserialize `clientContent` to a `Dictionary>` and map single string values to lists containing a single string during deserialization. – dbc Feb 12 '21 at 17:54
  • 1
    But what serializer are you using? [tag:json.net] or [tag:system.text.json]? If you are using [tag:json.net] you can use `SingleOrArrayConverter` from [How to handle both a single item and an array for the same property using JSON.net](https://stackoverflow.com/q/18994685/3744182). If you are using [tag:system.text.json] you can use `SingleOrArrayConverterFactory` from [How to handle both a single item and an array for the same property using System.Text.Json?](https://stackoverflow.com/q/59430728/3744182). – dbc Feb 12 '21 at 17:55

1 Answers1

0

Dictionary value cannot have two types,if you want to add them into 1 dictionary,you can only use Dictionary<string, string[]>,and put string to string[] as DavidG said.Or you can only use two dictionaries.Here is a demo to use Dictionary<string, string[]>.

Here is a demo:

Models:

public class Model1 
    {
        public Model2 clientConfDesc { get; set; }
    }
    public class Model2
    {
        public Dictionary<string, string[]> clientContent { get; set; }
       
    }

TestData:

{
    "clientConfDesc": 
    {
        "clientContent": 
        {
            "app.log.mail.port": "",
            "app.log.mail.protocol": "",
            "app.log.mail.receiver": "",
            "app.log.mail.server": "",
            "app.lookupDaemon.interval": "",
            "app.lookupDaemon.use": "yes",
            "app.remoteCall.ttl": "",
            "app.typeDef": ["5", "PD", "PEDIDO"]
        }
    }
}

Code:

var mydata = JsonConvert.DeserializeObject<JObject>(json);
                var obj= JsonConvert.DeserializeObject<JObject>(mydata["clientConfDesc"]["clientContent"].ToString());
                var model = new Model1 { clientConfDesc = new Model2 { clientContent = new Dictionary<string, string[]>() } };
                foreach (var item in obj)
                {
                    var s=item.Value.ToString();
                    if (s.Contains("["))
                    {
                        model.clientConfDesc.clientContent[item.Key] = JsonConvert.DeserializeObject<string[]>(s);
                    }
                    else if (s != "")
                    {
                        model.clientConfDesc.clientContent[item.Key] = new string[] { s };
                    }
                    else {
                        model.clientConfDesc.clientContent[item.Key] = new string[] { };
                    }
                }

Result: enter image description here

Yiyi You
  • 16,875
  • 1
  • 10
  • 22