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

时间:2015-05-04 01:48:02

标签: c# serialization servicestack ormlite-servicestack servicestack-text

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

1 个答案:

答案 0 :(得分:1)

问题是,您的班级Inventory有一个复杂类的词典键入

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

但是,根据ServiceStack.Text documentation

  

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

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

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

您可以做的是将项目序列化为一组键值对。自ServiceStack文本序列化器support [DataMember] aliases以及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是什么样的?您可能需要使序列化或类适应您实际接收的内容。