У меня есть стороннее приложение, которое отправляет на мой сайт POST-запросы с application / json в теле. Я могу записать строго типизированный объект как:
публичная строка Postback ([FromBody] MyResponse myResponse)
Моя проблема в том, что после того, как я так много поработал, меня направили на поддержку 2-го типа на той же конечной точке. Поэтому мне нужно принять строковое значение (вместо результата привязки модели), а затем JsonConvert строки к одному или другому из двух возможных типов.
Итак, я полагаю, что должен изменить подпись моего метода на:
публичная строка Postback ([FromBody] строка _sfResponse)
Но строка всегда показывает null (с директивой [FromBody] или без нее). Похоже, ModelBinder настаивает на участии. В любом случае, чтобы убедить его не делать этого?
На всякий случай что-нибудь про маршрутизацию:
routes.MapRoute(
"MyPostback",
url: "rest/V1/sync/update",
defaults: new { controller = "Admin", action = "MyPostback" }
);
Действие контроллера:
[System.Web.Mvc.HttpPost]
[System.Web.Mvc.AllowAnonymous]
public string MyPostback([System.Web.Http.FromBody][ModelBinder(typeof(MyResponseModelBinder))] MyResponseToProduct _sfResponse)
{
//stuff
}
Отправляемый json сложнее среднего, но имейте в виду, что когда подпись контроллера ссылается на строго типизированный объект, соответствующий этому json, все работает. (и повторюсь - мне нужно учитывать 2 разных типа входящих, поэтому мне нужно взять строку в начале вместо модели).
{
"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"
}
Я добавил настраиваемый связыватель модели, чтобы иметь возможность просматривать значения до того, как произойдет срабатывание контроллера:
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>()
};
}
}
Когда я проверяю значения в привязке пользовательской модели, controllerContext.HttpContext.Request.Form пуст (это отправка POST, поэтому тело действительно должно быть там, не так ли?)
Я могу видеть свои битовые данные в bindingContext.PropertyMetadata, но я не могу представить, что должен зайти так глубоко.
Очень странно, почему Request.Form пуст.