Reputation: 8468
I have a very weird problem here pertaining to ServiceStack.Text's serializer.
Suppose I have two classes, one called Person
and another called Address
.
Person:
public class Person
{
public string Name { get; set; }
public Dictionary<string,object> ExtraParams { get; set; }
}
Address:
public class Address
{
public string StreetName { get; set; }
}
In one of the methods I do this
var john = new Person
{
Name: "John",
ExtraParameters: new Dictionary<string, object>
{
{ "AddressList", new List<Address>{
new Address{ StreetName : "Avenue 1" }
}
}
}
};
I am using ServiceStack's ORMLite too. Now the problems comes when I try to retrieve the data from the database and cast it back to dictionary:
//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.
When I try to debug, the ExtraParameters is a Dictionary
, with key
named "AddressList", but the value
is actually a string - "[{StreetName:"Avenue 1"}]"
Any ideas where have I done wrong? I have looked up and down on SO about typecasting on the objects and dictionaries, but none of them seemed to have the same issue as I do.
I have set the following configs:
JsConfig.ExcludeTypeInfo = true;
JsConfig.ConvertObjectTypesIntoStringDictionary = true;
Upvotes: 2
Views: 1549
Reputation: 8468
While what Demiz said is true - that Inheritance in DTO is bad, I would really want to post a more accurate answer for the question just in case anyone really needs it.
Set the following flags:
JsConfig.ExcludeTypeInfo = false; //this is false by default
JsConfig.ConvertObjectTypesIntoStringDictionary = true; //must set this to true
For List of objects
that happens to be serialized, you would need to deserialize it as a list of objects first and cast each one of it back to the original 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);
Hope this one helps whoever needs it in the future.
Upvotes: 1
Reputation: 143319
Firstly storing object
is a bad idea for serialization and I'd strongly avoid using it.
Next you're breaking serialization of object
when you set:
JsConfig.ExcludeTypeInfo = true;
ServiceStack only adds the type info when it needs it, and this configuration prevents it from serializing the Type info in the JSON payload which is the only thing telling ServiceStack what to deserialize it back into which it needs because you're using a late-bound objects
Type where ServiceStack can't know what the type is otherwise.
Upvotes: 2