3

I have the following JSON payload:

{
    "id": 1,
    "foo": "bar",
    "bar": "foo",
    "attr_1": ["foo", "bar"],
    "attr_2": ["foo2", "bar2"]
}

I also have the following CLR object:

public class Obj
{
    public int Id { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }

    [JsonExtensionData]
    public IDictionary<string, string[]> Properties { get; set; }
}

If I try to deserialize it, it fails:

using (FileStream file = File.Open(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "file.txt"), FileMode.Open))
using (StreamReader reader = new StreamReader(file))
{
    Obj foo = JsonConvert.DeserializeObject<Obj>(reader.ReadToEnd());
}

There is already an answer to a similar question. However, it's not a solution to read and write each field one by one. What is the best way for me to deserialize leftover fields into IDictionary<string, string[]>?

Community
  • 1
  • 1
tugberk
  • 57,477
  • 67
  • 243
  • 335

1 Answers1

3

This line in Json.NET source code enforces the value type to be JToken. I think easiest way is to create another type for serialization.

public class SerializationModel
{
    public int Id { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }

    [JsonExtensionData]
    public IDictionary<string, JToken> Properties { get; set; }
}

class Model
{
    public int Id { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }
    public Dictionary<string, string[]> Properties { get; set; }
}

[Test]
public void DeserializeTest()
{
    string data = File.ReadAllText("data.txt");
    SerializationModel serializationModel = JsonConvert.DeserializeObject<SerializationModel>(data);

    Model model = new Model
    {
        Id = serializationModel.Id,
        Foo = serializationModel.Foo,
        Bar = serializationModel.Bar,
        Properties = serializationModel.Properties.ToDictionary(item => item.Key, pair => pair.Value.ToObject<string[]>())
    };

}
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
Ufuk Hacıoğulları
  • 37,978
  • 12
  • 114
  • 156
  • 1
    thanks! this is certainly a solution but not as naive as I want :s I'll try to see if I can extend or reimplement `JsonExtensionData`. – tugberk Jun 13 '14 at 18:10
  • @tugberk i'm just trying to make a normal CLR object from a *JsonElement* request body- but after deserilization the type in runtime is still JsonElement – Armin Torkashvand Apr 13 '21 at 18:49