I have a 3rd party app making POST submissions to my site with application/json in the body. I can capture a strongly typed object as:
public string Postback([FromBody]MyResponse myResponse)
My problem is that after having gotten this much working I'm directed to support a 2nd type at the same endpoint. Therefore I need to accept a string value (instead of the result of the model binder) and then JsonConvert the string to one or the other of the 2 possible types.
So I figure I should change my method's signature to:
public string Postback([FromBody]string _sfResponse)
But the string is always showing up null (with or without the [FromBody] directive). Seems the ModelBinder insists on participating. Anyway to convince him not to?
Just in case there's anything about routing:
routes.MapRoute(
"MyPostback",
url: "rest/V1/sync/update",
defaults: new { controller = "Admin", action = "MyPostback" }
);
The controller action:
[System.Web.Mvc.HttpPost]
[System.Web.Mvc.AllowAnonymous]
public string MyPostback([System.Web.Http.FromBody][ModelBinder(typeof(MyResponseModelBinder))] MyResponseToProduct _sfResponse)
{
//stuff
}
The json being sent is more complex that average but keep in mind that when the controller's signature is referencing a strongly typed object that matches that json everything works. (and to repeat -- I'm having to accommodate 2 different incoming types which is why I'm needing to take a string at the beginning instead of a model).
{
"results": [
{
"errors": {
"error": "No Error"
},
"sku": "70BWUS193045G81",
"status": "success",
"productId": "123"
},
{
"errors": {
"error": "No Error"
},
"sku": "70BWUS193045G82",
"status": "success",
"productId": "123"
}
],
"validationType": "products",
"messageId": "ac5ed64f-2957-51b4-8fbb-838e0480e7ad"
}
I've added a custom model binder just to be able to peek at values before the controller gets hit:
public class MyResponseModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
HttpRequestBase request = controllerContext.HttpContext.Request;
int id = Convert.ToInt32(request.Form.GetValues("Id"));
return new MyResponseToProduct()
{
results = new List<MyResponseToProduct.Result>()
};
}
}
When I inspect the values within the custom model binder the controllerContext.HttpContext.Request.Form is empty (this is a POST submission so the body really should be there, shouldn't it?)
I can see my bits data in the bindingContext.PropertyMetadata but I can't imagine I'm supposed to be going that deep.
Very strange why Request.Form is empty.