We're integrating with chargify http://www.chargify.com and I need to handle webhooks from Chargify in our MVC4/C# server. Chargify sends POST data in the (ruby) way - sub objects are delimited in square brackets, like so:
POST /1ffaj2f1 HTTP/1.1
X-Chargify-Webhook-Signature: 526ccfd9677668674eaa6ba5d447e93a
X-Chargify-Webhook-Id: 11238622
User-Agent: Ruby
Host: requestb.in
Content-Type: application/x-www-form-urlencoded
Content-Length: 5159
Connection: close
Accept-Encoding: gzip, deflate
Accept: */*; q=0.5, application/xml
id=11238622&event=payment_success&payload[subscription][activated_at]=2013-05-22%2001%3A25%3A20%20-0400&payload[subscription][balance_in_cents]=0&...
The issue is that on the .NET side, the default model binder does not like the square brackets[
]
and instead expects subobjects to be delimited in a dotted notation like a.b.c.d=value
What are my options to make the model binder work? I can think of the following:
[]
- hopefully being able to delegate to the default handler somehow. Dunno how to go about this - but would love to hear some thoughts.formcollection
param in the Action. Process the form collection keys to form a recursive dictionary based on the keys. This also means that I have to deal wiht strings throughout (for dates, ids etc etc)What's the best way and how do I go about it.
So I think I've finally solved this one using Request.Filter
property (msdn)
Also to note - There's no delegating handler in MVC - that's WebApi stuff (some of these things are made just to lead you astray!)
Basically, wrote a decorator over Stream that reads the input stream, replaces the square brackets with dots and then stores it in another stream. There's a check in Application_BeginRequest that sees if the input request is for the 'correct' controller and if so, creates a decorator instance and sets it to Request.Filter.
Code here. feel free to fork :)
[Update - 2013.08.19]: As noted by @benpage below in comments, we also need the original unmodified stream for SHA256 validation.
I ended up exposing the unmodified stream contents from the decorator and downcasting the Request.InputStream
property in the controller to get the unmodified content for signature validation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With