1

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

将对象保存在缓存上解决了,但它不能将它们加载回来(保存是可以的)。

下面是重现问题的代码。

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
}
}
4

1 回答 1

1

问题是您的类Inventory有一个由复杂类键入的字典:

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

但是,根据ServiceStack.Text 文档

任何 IDictionary 都被序列化为标准 JSON 对象,即:

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

不幸的是,您的Item类不能表示为简单的字符串,因此不能用作 JSON 属性名称

您可以做的是将您的项目序列化为键值对数组。由于 ServiceStack 文本序列化程序支持[DataMember]别名并且还支持忽略数据成员,因此您可以执行以下操作:

[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 是什么样子的?您可能需要使您的序列化或类适应您实际收到的内容。

于 2015-05-04T06:31:07.510 回答