ServiceStack 使用对象序列化和反序列化字典
ServiceStack Serialize and Deserialize Dictionary with Objects
这里有一个与 ServiceStack.Text 的序列化器有关的非常奇怪的问题。
假设我有两个 类,一个叫 Person
,另一个叫 Address
。
人:
public class Person
{
public string Name { get; set; }
public Dictionary<string,object> ExtraParams { get; set; }
}
地址:
public class Address
{
public string StreetName { get; set; }
}
我使用的其中一种方法
var john = new Person
{
Name: "John",
ExtraParameters: new Dictionary<string, object>
{
{ "AddressList", new List<Address>{
new Address{ StreetName : "Avenue 1" }
}
}
}
};
我也在使用 ServiceStack 的 ORMLite。现在,当我尝试从数据库中检索数据并将其转换回字典时,问题就来了:
//save to database
var id = db.Save(john)
//retrieve it back
var retrieved = db.SingleById<Person>(id);
//try to access the Address List
var name = retrieved.Name; //this gives "John"
var address = retrieved.ExtraParameters["AddressList"] as List<Address>; //gives null always , due to typecasting failed.
当我尝试调试时,ExtraParameters 是 一个 Dictionary
,key
名为 "AddressList",但是 value
实际上是一个字符串 - "[{StreetName:"Avenue 1"}]"
有什么想法我哪里做错了吗?我上下查看了关于对象和字典类型转换的 SO,但其中 none 似乎和我有同样的问题。
我设置了以下配置:
JsConfig.ExcludeTypeInfo = true;
JsConfig.ConvertObjectTypesIntoStringDictionary = true;
首先存储 object
是一个 bad idea for serialization,我强烈避免使用它。
接下来,当您设置时,您将破坏 object
的序列化:
JsConfig.ExcludeTypeInfo = true;
ServiceStack 仅在需要时添加类型信息,并且此配置阻止它序列化 JSON 有效负载中的类型信息,这是唯一告诉 ServiceStack 将其反序列化回所需内容的信息因为您使用的是后期绑定 objects
类型,否则 ServiceStack 无法知道该类型是什么。
虽然 Demiz 所说的是真实的 - DTO 中的继承很糟糕,但我真的很想 post 为这个问题提供一个更准确的答案,以防万一有人真的需要它。
设置以下标志:
JsConfig.ExcludeTypeInfo = false; //this is false by default
JsConfig.ConvertObjectTypesIntoStringDictionary = true; //must set this to true
对于碰巧被序列化的 objects
列表,您需要先将其反序列化为对象列表,然后将每个对象都转换回原始 class:
//save to database
var id = db.Save(john);
//retrieve it back
var retrieved = db.SingleById<Person>(id);
//try to access the Address List
var name = retrieved.Name; //this gives "John"
//cast it to list of objects first
var tempList = retrieved.ExtraParameters["AddressList"] as List<object>;
//cast each of the objects back to their original class;
var address = tempList.Select(x=> x as Address);
希望这篇能对以后有需要的人有所帮助。
这里有一个与 ServiceStack.Text 的序列化器有关的非常奇怪的问题。
假设我有两个 类,一个叫 Person
,另一个叫 Address
。
人:
public class Person
{
public string Name { get; set; }
public Dictionary<string,object> ExtraParams { get; set; }
}
地址:
public class Address
{
public string StreetName { get; set; }
}
我使用的其中一种方法
var john = new Person
{
Name: "John",
ExtraParameters: new Dictionary<string, object>
{
{ "AddressList", new List<Address>{
new Address{ StreetName : "Avenue 1" }
}
}
}
};
我也在使用 ServiceStack 的 ORMLite。现在,当我尝试从数据库中检索数据并将其转换回字典时,问题就来了:
//save to database
var id = db.Save(john)
//retrieve it back
var retrieved = db.SingleById<Person>(id);
//try to access the Address List
var name = retrieved.Name; //this gives "John"
var address = retrieved.ExtraParameters["AddressList"] as List<Address>; //gives null always , due to typecasting failed.
当我尝试调试时,ExtraParameters 是 一个 Dictionary
,key
名为 "AddressList",但是 value
实际上是一个字符串 - "[{StreetName:"Avenue 1"}]"
有什么想法我哪里做错了吗?我上下查看了关于对象和字典类型转换的 SO,但其中 none 似乎和我有同样的问题。
我设置了以下配置:
JsConfig.ExcludeTypeInfo = true;
JsConfig.ConvertObjectTypesIntoStringDictionary = true;
首先存储 object
是一个 bad idea for serialization,我强烈避免使用它。
接下来,当您设置时,您将破坏 object
的序列化:
JsConfig.ExcludeTypeInfo = true;
ServiceStack 仅在需要时添加类型信息,并且此配置阻止它序列化 JSON 有效负载中的类型信息,这是唯一告诉 ServiceStack 将其反序列化回所需内容的信息因为您使用的是后期绑定 objects
类型,否则 ServiceStack 无法知道该类型是什么。
虽然 Demiz 所说的是真实的 - DTO 中的继承很糟糕,但我真的很想 post 为这个问题提供一个更准确的答案,以防万一有人真的需要它。
设置以下标志:
JsConfig.ExcludeTypeInfo = false; //this is false by default
JsConfig.ConvertObjectTypesIntoStringDictionary = true; //must set this to true
对于碰巧被序列化的 objects
列表,您需要先将其反序列化为对象列表,然后将每个对象都转换回原始 class:
//save to database
var id = db.Save(john);
//retrieve it back
var retrieved = db.SingleById<Person>(id);
//try to access the Address List
var name = retrieved.Name; //this gives "John"
//cast it to list of objects first
var tempList = retrieved.ExtraParameters["AddressList"] as List<object>;
//cast each of the objects back to their original class;
var address = tempList.Select(x=> x as Address);
希望这篇能对以后有需要的人有所帮助。