POCO to Dictionary

I’d like to serialize a POCO (with nested POCO properties) to some kind of dictionary like: Dictionary<string,string> or Dictionary<string,object>, where the values are JSON strings of the property.

We need that so that we can pass it across various HTTP layers,and de-serialized back into the original POCO with a call like "{somejson}".FromJson<POCO>()

I’ve discovered that using ServiceStack.Text.TypeSerializer.ToStringDictionary<T>() does not do the job properly for complex properties, and I was looking for a way to do it properly.

For example, ToStringDictionary() for this POCO gives the following result:

    public class TestPoco
    {
        public NestedPoco Nested { get; set; }
    }

    public class NestedPoco
    {
        public object Object { get; set; }

        public string String { get; set; }

        public bool Bool { get; set; }

        public int Int { get; set; }
    }

gives a string value of the ‘Nested’ property as:

"{Object:anobject,String:astring,Bool:True,Int:99}"

which when deserialized with String.FromJson() gives null values for all the properties.

Is there a better extension I could use, or am I rolling my own?

ToStringDictionary() is only for serializing a flat POCO to a flat string Dictionary.

You can try T.ToObjectDictionary().ToJson() which should serialize to an object Dictionary then JSON fine, but you’re going to have issues trying to deserialize into an object as serializers won’t know what object it needs to deserialize into without type info. My recommendation is to steer clear of trying to deserialize late-bound objects which are a source of hidden runtime interoperability issues.

I would pass the Typed POCO wherever possible as that contains the most type info, when you want to treat it dynamically you can use T.ToObjectDictionary() and then later can convert it back with .FromObjectDictionary() but I’d only be serializing/deserializing to JSON from the Typed POCO.

Good call, thanks that makes sense.

OK, stuck again,

Let’s say I now have a serialized dto like this:

"{__type:MyNamespace.MyClass, MyNamespace,A:1,B:2,C:{D:3,E:4,F:5}}"

I have this string from another process where the DTO was serialized, and passed to my current process. Therefore I have no idea (in this process) what type MyClass is.It is unknown to this process.

Now, I need to send this string as the JSON of the body in a call to JsonServiceClient.Post() to some URL. I probably dont need the type information at all at this point.

The outcome I want in the service receiving this POST, is that the properties A,B,C map to the properties A,B,C on the request DTO of that service. say:

public class MyDto : IReturn<MyDtoResponse>
{
    public string A {get;set;}

    public string B {get;set;}

    public MyOtherDto C {get;set;}
}

public class MyOtherDto
{
    public string D {get;set;}

    public string E {get;set;}

    public string F {get;set;}
}

How would you do this?

That’s serialized JSV, not JSON which I’m assuming was created with the JSV TypeSerializer. I’d also highly recommend avoiding relying on __type info of late-bound objects or interfaces as you’re leaking internal C# type info on the wire in which internal refactoring will now cause runtime exceptions.

How would you do this?

So you’re not sending JSON, you’re sending JSV so you need to send it to a JSV endpoint and if you’re going to send it as a serialized string you need to use a raw/low-level HTTP Client like HTTP Utils with the MimeTypes.Jsv Content-Type instead of being able to make use of the generic typed JsvServiceClient.

Although I’m not sure what’s got you into this situation of having to send raw serialized outputs, which I wouldn’t be doing in the first place.

I got that string from reading an Azure queue.
The original object (that had this object (MyClass) as one of its properties) was put on the queue, so azure does the serialization to whatever I have now.

I guess I want to avoid JSV complications all together.

Do you think I should convert it myself to JSON before dumping on the queue?

If I do I get this to deal with:

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

I think I should be able to relay that JSON to the web service, (as you described) no?

It shouldn’t matter what format you use, you just need to make sure its deserialized using the same format and Type. But yeah you can send raw JSON with HTTP Utils. If you intend that another library needs to inspect the serialized data then I’d use JSON, otherwise I prefer JSV in serialized fields like App Settings, OrmLite blobs, Complex Type in QueryStrings, etc as it’s more human readable/writable.