Deserializing Stripe request

I am creating a stub service of my own for testing, and trying to define a request DTO for the POST /subscriptions endpoint (that I use to create a stripe subscription from a list of Stripe Plans).

The raw HTTP request on the wire looks like this:

POST https://localhost.dev:4456/subscriptions HTTP/1.1
Authorization: Bearer sk_test_blahblahblah
Stripe-Version: 2018-02-06
User-Agent: Stripe/v1 .NetBindings/16.1.0
X-Stripe-Client-User-Agent: {"bindings_version":"16.1.0","lang":".net","publisher":"stripe","lang_version":".NET Framework 4.5+","os_version":"Microsoft Windows NT 10.0.17134.0"}
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost.dev:4456
Content-Length: 177
Expect: 100-continue

items[0][plan]=aplanid&items[1][plan]=aplanid2&items[2][plan]=aplanid3&customer=acustomerid

It is created by the stripe-dotnet library.

Can you suggest what my request DTO should look like, to correctly deserialise this request?

This is what I have right now that does NOT work:

    [Route(@"/subscriptions", "POST")]
    public class CreateStripeSubscription : IReturn<StripeSubscription>
    {
        public string Customer { get; set; }

        public List<string> Items { get; set; }
    }

We don’t have native support for the complex types Stripe expects on the URL/form-data. In each case this is needed we have to add [IgnoreDataMember] on the collection properties to skip the default serialization and customize how the URL is generated by implementing IUrlFilter.ToUrl() method to append the complex collection properties to the URL in the format Stripe expects. Here’s an example of implementing Stripe’s POST /products/{Id} UpdateStripeProduct API:

Thanks, but how does that work for deserialization? I am trying to receive this request with its bazaar form data.

Stripe returns a JSON response which is deserialized into the Response DTO as normal.

Sorry @mythz,

I havent explained myself well enough.

I am creating a web service that emulates the stripe API, so I have to define a request DTO for the POST /subcriptions endpoint that will deserialize the HTTP request above.

However, I cannot figure out how to handle the bazaar POSTed form data:

items[0][plan]=aplanid&items[1][plan]=aplanid2&items[2][plan]=aplanid3&customer=acustomerid

Do you how?

We don’t have anything that deserializes Stripe’s form-data, you would need to accept the Request as a raw string and manually parse the string body.

Or potentially you may be able to read the IRequest.FormData collection to retrieve the posted variables in Key/Value pairs.

This works for us:

RequestBinders.Add(typeof(CreateStripeSubscription), httpReq =>
            {
                var dto = new CreateStripeSubscription
                {
                    Customer = httpReq.FormData["customer"],
                    Items = new List<string>()
                };

                Func<int, string> data = index =>
                {
                    return httpReq.FormData["items[{0}][plan]".Fmt(index)];
                };

                var itemIndex = 0;
                while (data(itemIndex) != null)
                {
                    dto.Items.Add(data(itemIndex));
                    itemIndex++;
                }

                return dto;
            });

Thanks

1 Like

Cool, string interpolation and local methods makes it look a little nicer :slight_smile:

string data(int index) => httpReq.FormData[$$"items[{index}][plan]"];