Search code examples
c#serializationservicestackservicestack-text

Control ServiceStack deserialization of POST variable and store in object


I would like to deserialize a post variable using ServiceStack's built in deserialization. But, I would like to make two changes that will provide me with some flexibility for another problem that I am attempting to solve.

[Route("/MyObject/{Property}", "POST")] OtherRoutes... public class MyObject:IReturn<MyObjectResponse>{ public string Property{ get; set; } public object Dto{ get; set; } Other properties... } public class CommodityType{ public int Id{ get; set; } public string CommodityTypeName{ get; set; } }

If the post variable class name matches {Property}, I want to create that DTO class and store that in the Dto object. I want everything else to deserialize normally.

For example if I post to: "example.com/API/MyObject/CommodityType" the following json:

{ "CommodityType":{ "Id": 1, "CommodityTypeName": "Commercial Services" } }

if(MyObject.Property == POST.ObjectName){ // in this example Post.ObjectName = "CommodityType" // Use Reflection to create object of type MyObject.Property // Deserialize into the object created by reflection // MyObject.Dto = Deserialized object }

Is this a situation where I could use Request and Response filters? Should I create a custom request binder? Is there another way to approach this?


Solution

  • Not sure if it's an option, but from your example I would be including a property for CommodityType with the type that you want to deserialize into so the JSON Serializer can populate it for you, e.g:

    public Request
    {
        public CommodityType CommodityType { get; set; }
    }
    

    It's ok if it doesn't exist as it will just be left as null.

    Depending on the shape of the Request DTO property, another option might be to make the dynamic part an object and Configure ServiceStack's JSON Serializer to convert object types to string Dictionary, e.g:

    JsConfig.ConvertObjectTypesIntoStringDictionary = true; // in AppHost
    
    public Request
    {
        public object CommodityType { get; set; }
    }
    

    In which case object will be deserialized into a loose-typed Dictionary, which you can inspect change it to a strong type in your Request Filter.

    Otherwise if you want to further change the default deserialization behavior, you'll need to use a Custom Request Binder and handle custom deserialization and handle the deserialization yourself.

    ServiceStack.Text includes support for parsing arbitrary JSON with JsonObject API's, see links in Custom Deserialization for some examples.