Danny Huyn
Danny Huyn

Reputation: 21

ServiceStack - Dynamic/Object in DTO

I am running into an issue while looking at SS.

I am writing a custom Stripe implementation and got stuck on web hooks, this in particular: https://stripe.com/docs/api#event_object

data->object - this can be anything.

Here is my DTO for it:

public class StripeEvent
{
    public string id { get; set; }

    public StripeEventData data { get; set; }

    public string type { get; set; }
}

[DataContract]
public class StripeEventData
{
    [DataMember(Name = "object")]
    public object _object { get; set; }
}

My hope is to basically just get that object as a string, and then parse it:

var invoice = (StripeInvoice)JsonSerializer.DeserializeFromString<StripeInvoice>(request.data._object.ToString());

Unfortunately the data that is returned from ToString does not have quotes surrounding each json property's name:

Capture

So, the DeserializeFromString returns an object that has everything nulled out.

Why does SS internally strip the quotes out? Is this the proper way to handle a json member that can be one of many different types? I did try the dynamic stuff, but did not have any luck with that either - basically the same result with missing quotes.

I searched very thoroughly for the use of objects and dynamic within DTOs, but there really was nothing that helped with this question.

Thank you!

Upvotes: 2

Views: 858

Answers (1)

mythz
mythz

Reputation: 143284

The issue is that you should never have an object type in DTOs as the serializer has no idea what concrete type to deserialize back into.

The Stripe documentation says object is a hash which you should be able to use a Dictionary to capture, e.g:

public class StripeEventData
{
    public Dictionary<string,string> @object { get; set; }
}

Or as an alternative you could use JsonObject which provides a flexible API to access dynamic data.

This will work for flat object structures, but for complex nested object structures you'll need to create Custom Typed DTOs, e.g:

public class StripeEventInvoice
{
    public string id { get; set; }    
    public StripeEventDataInvoice data { get; set; }
    public string type { get; set; }
}

public class StripeEventData
{
    public StripeInvoice @object { get; set; }
}

Upvotes: 2

Related Questions