ModelBinding: POST data (possibly from Ruby) in MVC4/C#

£可爱£侵袭症+ 提交于 2019-12-10 13:52:45

问题


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:

  1. Hook into the request with a delegating handler, read the req body and replace [] with dot (.). However, this feels dicey at the least
  2. Write a custom model binder that will work with [] - hopefully being able to delegate to the default handler somehow. Dunno how to go about this - but would love to hear some thoughts.
  3. Just use a 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.


回答1:


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.



来源:https://stackoverflow.com/questions/17290035/modelbinding-post-data-possibly-from-ruby-in-mvc4-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!