System.Text: JsonSerializer.Deserialize with generics

Viewed 3521

I am trying to make sense of the documentation:

My goal is simply to load DICOM/JSON using System.Text.Json.JsonSerializer (dotnet 5.0). The steps are easy from C# to JSON:

private class DataElement<T>
{
  public string vr { get; set; }
  public List<T> Value { get; set; }
}
[...]
var dataset = new Dictionary<string, object>();
dataset.Add("00100021", new DataElement<string>() { vr = "LO", Value = new List<string>(1) { "Hospital A" }});
dataset.Add("00201206", new DataElement<int>() { vr = "IS", Value = new List<int>(1) { 4 } });
dataset.Add("00101030", new DataElement<double>() { vr = "DS", Value = new List<double>(1) { 72.5 } });
string jsonString = JsonSerializer.Serialize(dataset, serializeOptions);
File.WriteAllBytes("ds.json", Encoding.UTF8.GetBytes(jsonString));

But doing it the other way around seems much more complex.

How should I implement the custom converters for those 3 possible generics (string, int or double) ?

3 Answers

It is more complex, but doable. Try decoding them in order of int -> double -> string since a double cannot be an int and anything that is not an int or double should be a string.

var intval = 0;
var dblval = 0.0;

if (int.TryParse(value, out intval)
   return intval;

if (double.TryParse(value, out dblval)
   return dblval;

return value.ToString();

If you want to use the System.Text deserializer, it will get you close if you supply what you are deserializing. Try this:

JsonSerializer.Deserialize<Dictionary<string, DataElement<object>>>(jsonString);

However if you use the NewtonSoft.Json deserializer, you will still want to let it know what you are expecting, but it will give you back the actual types for the numeric values; and the syntax looks like this:

JsonConvert.DeserializeObject<Dictionary<string, DataElement<object>>>(jsonString);

My goal is simply to load DICOM/JSON using System.Text.Json.JsonSerializer.

If that is the case then may I suggest you use NewtonSoft's Json converter. It's a lot easier to use and understand (even the Custom Converters).

Example:

Initialize

var dataset = new Dictionary<string, object>();
dataset.Add("00100021", new DataElement<string>() { vr = "LO", Value = new List<string>(1) { "Hospital A" } });
dataset.Add("00201206", new DataElement<int>() { vr = "IS", Value = new List<int>(1) { 4 } });
dataset.Add("00101030", new DataElement<double>() { vr = "DS", Value = new List<double>(1) { 72.5 } });

Save

// Create a string for it
var json = JsonConvert.Serialize(MyDictionary);

Load

// Similar to your original object
var dict = JsonConvert.DeserializeObject<Dictionary<string, DataElement<object>>>(json);

Test

foreach (var element in dict)
{
    Console.WriteLine(JsonConvert.SerializeObject(element));
}

enter image description here


For additional info on custom converters see link below. But with your goal in mind I don't think a custom converter is required. Especially if you just want a Dictionary<string, object> out.

https://www.newtonsoft.com/json/help/html/CustomJsonConverterGeneric.htm

Why NewtonSoft

I've had issues with the inbuilt JsonSerializer package converting objects to nulls, especially when networking.

Related