Evyatar
Evyatar

Reputation: 1157

Trying to convert JSON to [Key,Value] dictionary

I'm using Newtonsoft.Json any trying to convert JSON to Dictionary<string,string>

This is the JSON file:

[
{
        "<p dir=\"rtl\">":""
},
{
        "<p>":""
},
{
        "<p dir='rtl'>":""
},
{
        "<div dir='rtl'>":""
},
{
        "<div>":""
},
{
        "<div dir=\"rtl\">":""
},
{
        "<script>":"&lt;script&gt;"/
},
{
        "</script>":"&lt;/script&gt;"
},
{
        "<button>":"&lt;button&gt;"
},
{
        "<button":"&lt;button"
},
{
        "</button>":"&lt;/button&gt;"
},
{
        "&lt;br&gt;":"<br>"
},
{
        "&lt;br /&gt;":"<br>"
},
{
        "&lt;br/&gt;":"<br>"
},
{
        "&lt;/br&gt;":"<br>"
},
{
        "\"":""
}
]

And this is the code:

var replaceTags = System.IO.File.ReadAllText(JSON_FILE_PATH);
Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(replaceTags);

And I'm got the following exception:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.

Why Its happend?

Thanks!

Upvotes: 3

Views: 7275

Answers (3)

Abion47
Abion47

Reputation: 24616

Like I said in the comments, your JSON isn't a dictionary, but rather an array of dictionaries. You can merge them all into a single dictionary like so:

string input = File.ReadAllText("file.json");
var jsonObj = JsonConvert.DeserializeObject<Dictionary<string, string>[]>(input);

var dict = jsonObj.SelectMany(d => d)
                  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

However, because of the way the JSON is structured, there's not going to be any guarantee that there won't be duplicate keys. To prevent this, you could also filter any potential duplicates out:

var dict = jsonObj.SelectMany(d => d)
                  .GroupBy(kvp => kvp.Key)
                  .Select(g => g.First())
                  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

In my opinion, though, unless there is a very good reason that you absolutely need to serialize this JSON into a single Dictionary, you should just leave it as an array of dictionaries (since that's what it is):

string input = File.ReadAllText("file.json");
var dictArray = JsonConvert.DeserializeObject<Dictionary<string, string>[]>(input);

Upvotes: 4

Dec
Dec

Reputation: 303

You're JSON isn't right, for a dictionary of type string,string. Try changing the format to match:

{"key1":"value1","key2":"value2"}

Upvotes: 1

Wheels73
Wheels73

Reputation: 2890

Here is a simple example of serializing a dictionary of string,string to a JSON text. Your text will obviously come from your file path once read.

var myd = new Dictionary<string, string>();
            myd.Add("1","A");
            myd.Add("2", "B");

            var dText = JsonConvert.SerializeObject(myd);

This gives you the below string.

{"1":"A","2":"B"}

This will then deserialize back to a dictionary.

var restoredDictionary = JsonConvert.DeserializeObject<Dictionary<string,string>>(dText);

Suggest you reverse engineer this. Manually create a dictionary with the data you are expecting. Serialize it and see what the file contents should be.

You may find that whatever is generating the source file in "JSON_FILE_PATH" is the source of your problem.

Upvotes: 3

Related Questions