【问题标题】:ServiceStack Serialize and Deserialize Dictionary with ObjectsServiceStack 使用对象序列化和反序列化字典
【发布时间】:2016-06-14 10:31:37
【问题描述】:

我在这里遇到一个与 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"}]"

任何想法我做错了什么?关于对象和字典的类型转换,我一直在上上下下查看,但似乎没有一个和我有同样的问题。

我设置了以下配置:

JsConfig.ExcludeTypeInfo = true;
JsConfig.ConvertObjectTypesIntoStringDictionary = true;

【问题讨论】:

  • 尝试使用Type Serializer将AddressList反序列化为List&lt;Address&gt;。

标签: c# servicestack servicestack-text


【解决方案1】:

首先存储object 是bad idea for serialization,我强烈避免使用它。

接下来,您将在设置时打破object 的序列化:

JsConfig.ExcludeTypeInfo = true;

ServiceStack 仅在需要时添加类型信息,并且此配置阻止它序列化 JSON 有效负载中的类型信息,这是唯一告诉 ServiceStack 将什么反序列化回它需要的内容,因为您使用的是后期绑定 objects 类型,其中 ServiceStack 无法知道该类型是什么。

【讨论】:

  • 是的,你是对的@mythz。我必须将 JsConfig.ExcludeTypeInfo 设置为 false(默认情况下)。
  • @CozyAzure 你只需要不设置它,即首先删除配置。
【解决方案2】:

虽然 Demiz 说的是真的 - DTO 中的继承是不好的,但我真的想为这个问题发布一个更准确的答案,以防万一有人真的需要它。

设置以下标志:

JsConfig.ExcludeTypeInfo = false; //this is false by default
JsConfig.ConvertObjectTypesIntoStringDictionary = true; //must set this to true

对于碰巧被序列化的objects 列表,您需要先将其反序列化为对象列表,然后将其中的每一个都转换回原始类:

//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); 

希望这个对以后需要的人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多