9

ASP.Net MVC でコントローラーに投稿するときに、標準の QueryStrings ではなく JSON を送信できるようにしたいと考えています。フロントエンドの機能が正常に動作しています (JSON オブジェクトを構築してから送信します)。

問題は、MVC フレームワークに同梱されているデフォルトの ModelBinders がこれをサポートしていないコントローラー側にあります。

これを回避する方法の組み合わせを見てきました。そのうちの 1 つは、オブジェクトをパラメーターとして受け取り、JSON ライブラリを使用してそれを逆シリアル化し、それをアクション パラメーターに追加するフィルターを適用することです。これは理想的ではありません。

もう 1 つの優れた方法は、カスタム モデル バインダーを使用することです。私が見たものはすべて、モデルが 1 つしかなく、それが変数ではなくクラスであると想定しています。複数あると壊れます。

他の誰かがこれに遭遇しましたか?私が持っていたアイデアの 1 つは、MVC が FormCollection を処理する方法をオーバーライドしてそこでインターセプトし、値を自分でコレクションに追加して、MVC が通常の方法で残りを実行できることを期待することでした。それが可能かどうか誰にもわかりますか?

重要な問題は、私のビューモデルは以前と変わらないため、私の問題はバインドにあるのではないということです。問題は、JSON Post から値を取得することです。

私が正しければ、MVC は QueryString から値を取得し、それをフォーム コレクションに入れ、それを ModelBinding に使用します。FormCollection の割り当て方法を変更するのが正しい方法ではないでしょうか。

アクションの例:

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

通常のバインドは機能しますが、JSON は機能しません。モデル バインダーのすべての例も機能しません。これまでの私の最善の解決策は、オブジェクトを辞書に変換し、各パラメーターをループして一致させることです。理想的ではないようです。

4

1 に答える 1

8

次のような 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 にフォールバックする必要があります。異なる結果を経験していますか?

于 2010-01-26T16:42:42.117 に答える