ServiceStack ormlite json 不从数据库反序列化

ServiceStack ormlite json does not deserialize from database

ServiceStack ORMLite 不会从 Postgresql 中反序列化我的 class。

将对象保留在缓存中可以解决,但无法将它们加载回来(保存没问题)。

下面是重现问题的代码。

void Main()
{
    var inv = new Inventory();
    inv.Items.Add(new Item{Id=1,CreatedAt=DateTime.Now, Key="potion10", Descriptions=new Dictionary<int, string>{{1,"Poção que recupera um pouco de vida."},{2,"Potion that restores a little of health."}}, HealthModifier=10,IsUseable=true, Names=new Dictionary<int, string>{{1,"Poção Leve"},{2,"Minor Potion"}}, UpdatedAt=DateTime.Now}, 2);

    var invJson = inv.ToJson().To<Inventory>(); // can't deserialize
    var invJsv = inv.ToJsv().To<Inventory>(); // same problem
}

public class Item
{
    public Item()
    {
        Names = new Dictionary<int, string>();
        Descriptions = new Dictionary<int, string>();
    }

    public long Id { get; set; }

    public string Key { get; set; }

    public Dictionary<int, string> Names { get; set; }

    public Dictionary<int, string> Descriptions { get; set; }

    public int HealthModifier { get; set; }

    public bool IsUseable { get; set; }

    public DateTime CreatedAt { get; set; }

    public DateTime UpdatedAt { get; set; }
}

public class Inventory
{
    public Inventory()
    {
        Items = new Dictionary<Item, int>();
    }

    public Dictionary<Item, int> Items { get; set; }
}

Postgresql 上的 JSON 与上面的代码相同。

{
    "Items":{
        "{"Id":1,
        "Key":"potion10",
        "Names":{
            "1":"Poção Leve",
            "2":"Minor Potion"
        },
        "Descriptions":{
            "1":"Poção que recupera um pouco de vida.",
            "2":"Potion that restores a little of health."
        },
        "HealthModifier":10,
        "IsUseable":true,
        "CreatedAt":"\/Date(1430743156138-0300)\/",
        "UpdatedAt":"\/Date(1430743156139-0300)\/"
    }:2
}
}

问题是你的 class Inventory 有一个字典 keyed 由一个复杂的 class:

public Dictionary<Item, int> Items { get; set; }

但是,根据 ServiceStack.Text documentation

Any IDictionary is serialized into a standard JSON object, i.e:

     {"A":1,"B":2,"C":3,"D":4}

不幸的是,您的 Item class 不能表示为简单字符串,因此不能用作 JSON 属性 name.

您可以将项目序列化为键值对数组。由于 ServiceStack 文本序列化程序 support [DataMember] aliases and also support ignoring of data members,您可以执行以下操作:

[DataContract]
public class Inventory
{
    public Inventory()
    {
        Items = new Dictionary<Item, int>();
    }

    [IgnoreDataMember]
    public Dictionary<Item, int> Items { get; set; }

    [DataMember(Name = "Items")]
    public KeyValuePair<Item, int> [] ItemArray
    {
        get
        {
            return Items == null ? null : Items.ToArray();
        }
        set
        {
            (Items ?? (Items = new Dictionary<Item, int>())).Clear();
            if (value != null)
                foreach (var pair in value)
                    Items[pair.Key] = pair.Value;
        }
    }
}

这将序列化和反序列化有效的 JSON,它应该看起来像这样:

{
  "Items": [
    {
      "Key": {
        "Id": 1,
        "Key": "potion10",
        "Names": {
          "1": "Poção Leve",
          "2": "Minor Potion"
        },
        "Descriptions": {
          "1": "Poção que recupera um pouco de vida.",
          "2": "Potion that restores a little of health."
        },
        "HealthModifier": 10,
        "IsUseable": true,
        "CreatedAt": "2015-05-04T02:07:10.7216263-04:00",
        "UpdatedAt": "2015-05-04T02:07:10.7216263-04:00"
      },
      "Value": 2
    }
  ]
}

但是,您提到您的 JSON 来自 Postgresql。 JSON 是什么样子的?您可能需要调整您的序列化或 classes 以适应您实际收到的内容。