3

Is there a way to get the DefaultModelBinder to work when the data is POSTed using x-www-form-urlencoded instead of application/json, but the actual payload of the value is JSON encoded?

For example, I am being sent a single key-value-pair:

key: 'events' 
value: '[{"event":"inbound","ts":1350928095,"msg":{"raw_msg":"Received"}}]'

where the value contains JSON array in this case.

NOTE: The POST is coming from a 3rd party so I cannot control it.

Jack Ukleja
  • 13,061
  • 11
  • 72
  • 113
  • 1
    I would've changed it myself, but there is a minimum amount of characters you need to change before it is an accepted edit. I didn't want to reword your question just to satisfy my OCD more quickly ;) – TheZ Oct 25 '12 at 15:36

3 Answers3

0

In general, the answer is "Sure. Just use 'NAME=VALUE' (e.g. 'data=MYJSON'), and don't forget to encode before you send."

Here's an example:

But, re-reading your question, you're using MVC4. That might impose restrictions over a simple C# or Java program :(

Community
  • 1
  • 1
paulsm4
  • 114,292
  • 17
  • 138
  • 190
0

I don't think so. You can either change the client to post application/json content type or write a custom model binder.

xing
  • 447
  • 2
  • 6
0

If you need this behavior in a single action use the JavaScriptSerializer to deserialize the JSON content into a collection and validate the collection using UpdateModel/TryUpdateModel methods.

If you need in many actions then you have to go for a custom model binder by inheriting the DefaultModelBinder and override the CreateModel method. In the CreateModel method use the JavaScriptSerializer to create the objects from the POSTed value.

public class CustomModelBinder: DefaultModelBinder
{
   protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
  {
     // JavaScriptSerializer serializer = new JavaScriptSerializer();
     // return serializer.DeserializeObject(read the value from request);
  }
}

Now you can reuse the CustomModelBinder across actions using the Bind attribute.

VJAI
  • 32,167
  • 23
  • 102
  • 164