ASP.Net MVC: отправка JSON контроллеру

Я хочу иметь возможность отправлять JSON в отличие от стандартных QueryStrings при создании сообщения на мои контроллеры в ASP.Net MVC. У меня есть функции Front-End, которые отлично работают (строят, а затем отправляют объекты JSON).

Проблема находится на стороне контроллера, где стандартные модели ModelBinders, поставляемые с инфраструктурой MVC, не поддерживают это.

Я видел комбинацию способов вокруг этого, один из них - применить фильтр, который принимает объект в качестве параметра, использует библиотеку JSON для де-сериализации и добавляет это к параметрам действия. Это не идеально.

Другим, лучшим способом является использование настраиваемого связующего объекта. Все те, что я видел, предполагают, что у вас будет только одна модель, и это будет класс, а не переменная. Если у вас несколько, оно ломается.

Кто-нибудь еще столкнулся с этим? Одна из моих идей заключалась в том, что я мог бы просто переопределить, как MVC имеет дело с FormCollection и перехватывает его, добавляя значения в коллекцию самостоятельно и надеясь, что MVC может сделать все остальное в ней обычным способом. Кто-нибудь знает, возможно ли это?

Ключевой проблемой, я думаю, является то, что моя проблема связана не с привязкой, потому что мои модели просмотра не отличаются от того, как они раньше. Проблема заключается в получении значений из сообщения JSON.

Если я прав, MVC получает значения из QueryString и помещает их в коллекцию форм, которая затем используется для ModelBinding. Не следует ли правильному методу изменить способ присвоения FormCollection?

Пример действия:

public ActionResult MyFirstAction(Int32 ID, PersonObject Person, ClassObject ClassDetails)
{
//etc
}

Обычная работа по связыванию, JSON не работает, и весь пример Model Binders тоже не будет работать. Мое лучшее решение до сих пор заключается в том, чтобы преобразовать объект в словарь и цикл, хотя каждый параметр и соответствовать ему. Не кажется идеальным.

Ответ 1

Я использую настраиваемое связующее устройство для json следующим образом:

public class JsonModelBinder<T> : IModelBinder {
    private string key;

    public JsonModelBinder(string requestKey) {
        this.key = requestKey;
    }

    public object BindModel(ControllerContext controllerContext, ...) {
        var json = controllerContext.HttpContext.Request[key];
        return new JsonSerializer().Deserialize<T>(json);
    }
}

И затем подключите его в Global.asax.cs следующим образом:

ModelBinders.Binders.Add(
    typeof(Product),
    new JsonModelBinder<Product>("ProductJson"));

Подробнее об этом вы можете прочитать здесь: Наследование зла: эпическая ошибка DataAnnotationsModelBinder

ИЗМЕНИТЬ

JsonModelBinder следует использовать в параметре действия контроллера, введенном только как продукт. Int32 и ClassObject должны вернуться к DefaultModelBinder. Вы испытываете другой результат?