DerApe
DerApe

Reputation: 3175

Generic JSON deserialization in grid

Hi I'm using JSON for de/serialization items in my grid control (copy/paste feature). I want to use JSON because the copy paste has to work across application domain.

The value type of each cell can be different (simple and complex types).

class CellItem<TValue>
{
  public TValue Value { get; set; }
  public int GridColumnIndex { get; set; }
  public int GridRowIndex { get; set; }
}

In order to do the serialization I need to get the cell position and store it's value. So I created a serialization type

public class MatrixItem
{
  public int ColumnIndex { get; set; }
  public int RowIndex { get; set; }
  public object Value { get; set; }
}

and put them in a list to serialize them into the clipboard. That works quite fine.

Now when I do deserialization I want to tell JSON which type to deserialize. How can I do that? I know the type information is not stored in the serialization string so I have to take care of that in code.

I somehow need to ask the CellItem which type to use for deserialization and let the converter know. But I'm not sure how to do that.

There is something like [JsonConverter(typeof(*))] but that needs a compile time known converter and the converter would change during runtime.

Upvotes: 1

Views: 100

Answers (1)

Felix D.
Felix D.

Reputation: 5113

Maybe this could help you:

Let's say you got an interface:

interface Fruit
{
    bool IsSweet();
}

You then got several classes representing your data:

public class Apple : Fruit
{
    public bool IsSweet()
    {
        return false;
    }
}

public class Banana : Fruit
{
    public bool IsSweet()
    {
        return true;
    }
}

Now when it comes to serialization you would like to store the type, so when u deserialize you know if it was a Banana or an Apple.

You can do so using JsonSerializerSettings:

List<Fruit> fruits = new List<Fruit>();

fruits.Add(new Banana());
fruits.Add(new Apple());

JsonSerializerSettings settings = new JsonSerializerSettings();

//This is the IMPORTANT part
settings.TypeNameHandling = TypeNameHandling.All;

string json = JsonConvert.SerializeObject(fruits, settings);

The Json will look like this:

{
  "$type": "System.Collections.Generic.List`1[[YourNamespace.Fruit, YourNamespace]], mscorlib",
  "$values": [
    {
      "$type": "YourNamespace.Banana, YourNamespace"
    },
    {
      "$type": "YourNamespace.Apple, YourNamespace"
    }
  ]
}

Now when u deserialize you want get the derived type, not the interface: Simply pass the settings used above again:

var deserializedFruites = (List<Fruit>)JsonConvert.DeserializeObject(json, settings);

Count = 2
[0]: {YourNamespace.Banana}
[1]: {YourNamespace.Apple}

Now to adapt to your specific problem I guess it would be the easiest if you just export the type to json too.

Upvotes: 1

Related Questions