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 以适应您实际收到的内容。
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 以适应您实际收到的内容。