0

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?

1 Answers1

0

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.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • It sounds like the second option is what I will need to do. Would it be possible for you to clarify, "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." in particular the "which you can inspect change it to a strong type in your Request Filter" – Asa Beckstead Feb 05 '15 at 19:41
  • Without any `__type` info, ServiceStack has no way of determining what type an `object` property should be deserialized into which is why `object` properties are left as a `string` by default. This can be changed with `JsConfig.ConvertObjectTypesIntoStringDictionary = true` to deserialize it into a `Dictionary`. Changing it into a strong type just means replacing the dictionary with your own object instance which you can do here since it's an `object` property so it can be set to any instance. – mythz Feb 05 '15 at 19:48