ポストバックではなくAJAXによるモデルバインディングチェックボックスを使用するとMVC 3の問題が発生する

私はモデルのチェックボックスをフォームからサーバー上のアクションにブール値を含むカスタムオブジェクトでバインドする問題があります。

Googleにはこれには多くの問題があり、良い解決策はありません。私は複数のことを試してきましたが、問題は通常のポストバックではなくajaxコールを介して送信されたときにのみ発生するようです。

私は私のプロジェクトで以下を持っています(簡潔さのために減らしました):

表示

@Html.LabelFor(model => model.TillAccess)
@Html.CheckBoxFor(m => m.TillAccess)

モデル

public class CreateUserModel 
{
    public Boolean TillAccess { get; set; } 
}

コントローラの操作

[HttpPost]
public virtual ActionResult CreateUserWizard(CreateUserModel model)
{
   ...
}

フォームに2つのボタンを追加しました.1つはポストバックとして送信され、動作します。それは、私がfiddler2でチェックすると、ポストバックで以下を送信します:

TillAccess=true&TillAccess=false

それは、私がajaxボタンを押して送信しても動作しない場合、以下を送信します:

{"TillAccess":["true","false"]}

MVCモデルがこの作業を停止するJSONをバインドする方法に問題がありますか?

私はAJAX(これは私が大量に使用します)を使って作業することはできません。他のすべてのフィールドは、チェックボックスだけで結構です。通常のポストバックがJSONシリアライザやモデルバインダに関する問題を示唆しています。 MVCのために?

更新

ajax呼び出しは次のとおりです。

function CreateUser() {
        var FormData = JSON.stringify($('#CreateUserWizardForm').serializeObject());

        $.ajax({
            url: '@Url.Action(MVC.User.User.ActionNames.CreateUserWizard)',
            data: FormData,
            contentType: "application/json",
            dataType: "json",
            type: 'POST',
            cache: 'false',
            success: function (response) {
                alert('successfully created user!');
            },
            error: function (xhr) {
                alert('There was an error creating a user');
            }
        });
    }

完全なajax投稿は以下のとおりです:

{"BusinessUnitId":"cd56b710-0171-11e1-be50-0800200c9a66","Person.Salutation":"","Person.FirstName":"","Person.LastName":"","‌​TillAccess":["true","false"],"OfficeAccess":"false","TillLoginId":"","OfficeEmail‌​Address":"","OfficePassword":""}

更新

serializeObjectメソッドがインターネットからダウンロードされました(私がjsonの投稿に問題があったため)、次のようになります:

$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

更新

このserializeObjectメソッドを使用した理由は、次のinbuilt呼び出しを使用した場合に受け取ったエラーが原因でした。

$('#CreateUserWizardForm').serialize()

それはポストを作成しました:

BusinessUnitId=cd56b710-0171-11e1-be50-0800200c9a66&Person.Salutation=&Person.FirstName=&Person.LastName=&TillAccess=true&TillAccess=false&OfficeAccess=false&TillLoginId=&OfficeEmailAddress=&OfficePassword=

これは私に次のようなエラーを与えました:

System.ArgumentException: Invalid JSON primitive: BusinessUnitId.

更新 - ANSWER (I tried to add my answer at the bottom, but it won't let me)

解決策を見つけました。私のAJAXコールは間違っていました。次のように変更して動作しています。

$.ajax({
            url: '@Url.Action(MVC.User.User.ActionNames.CreateUserWizard)',
            data: $('#CreateUserWizardForm').serialize(),
            type: 'POST',
            cache: 'false',
            success: function (response) {
                alert('successfully created user!');
            },
            error: function (xhr) {
                alert('There was an error creating a user');
            }
        });

古いAJAX呼び出し:

var FormData = JSON.stringify($('#CreateUserWizardForm').serializeObject());

        $.ajax({
            url: '@Url.Action(MVC.User.User.ActionNames.CreateUserWizard)',
            data: FormData,
            contentType: "application/json",
            dataType: "json",
            type: 'POST',
            cache: 'false',
            success: function (response) {
                alert('successfully created user!');
            },
            error: function (xhr) {
                alert('There was an error creating a user');
            }
        });
3
serializeObject 関数を name ではなく id を使用するように変更してみてください。 Html.CheckBoxFor id のない2番目の入力を作成しますが、同じ name
追加された 著者 Tim B James,

2 答え

私は解決策を見つけた。私のAJAXコールは間違っていました。私はそれを次のように変更して動作しています。

$.ajax({
            url: '@Url.Action(MVC.User.User.ActionNames.CreateUserWizard)',
            data: $('#CreateUserWizardForm').serialize(),
            type: 'POST',
            cache: 'false',
            success: function (response) {
                alert('successfully created user!');
            },
            error: function (xhr) {
                alert('There was an error creating a user');
            }
        });

古いAJAX呼び出し:

var FormData = JSON.stringify($('#CreateUserWizardForm').serializeObject());

        $.ajax({
            url: '@Url.Action(MVC.User.User.ActionNames.CreateUserWizard)',
            data: FormData,
            contentType: "application/json",
            dataType: "json",
            type: 'POST',
            cache: 'false',
            success: function (response) {
                alert('successfully created user!');
            },
            error: function (xhr) {
                alert('There was an error creating a user');
            }
        });
2
追加された

あなたは送る必要があります

{"model":{"TillAccess":["true","false"]}}

モデルバインダーは、 model パラメーターと任意のプロパティーを一致させることができないため、モデルをバインドしません。

更新:

TillAccess property is of type bool, but you're sending an array of 2 strings. I think this is a problem

0
追加された
これは、あなたの $( '#CreateUserWizardForm')serializeObject()が誤ったJSONを返すことを意味します。
追加された 著者 Jakub Konecki,
私は serializeObject()が、同じ名前属性を持つ2つのhtml要素を作成する @ Html.CheckBoxFor の結果としてjsonを作成していると思います
追加された 著者 Tim B James,
このJsonはフレームワークによって私のために自動生成され、他のすべてのフィールドは正しくバインドされているので、問題があることはわかりません。完全な投稿は次のとおりです:{"BusinessUnitId": "cd56b710-0171-11e1-be50-0800200c9a66"、 "Pe‌ rson.Salutation": ""、‌ "Person.FirstName": "‌" 、 "Person.LastName":‌ ""、 "TillAccess":["tr‌ ue"、 "false"]、 "Office‌ Access": "false"、 "Til‌ lLoginId" 、 "Office‌ EmailAddress": ""、 "‌ ficePassword": ""}
追加された 著者 eyeballpaul,
繰り返しますが、これは私が生成しているものではなく、Ajax側のシリアライズメソッドです。つまり、 "var FormData = JSON.stringify($( '#CreateUserWizardForm')。serializeObject())‌;"
追加された 著者 eyeballpaul,
ああ、私はserializeObject()メソッドがインターネットからコピーされたものであり、jQueryに何か組み込みではないことに気がつきました。私は私のポストに上記の機能を掲載します。また、Jsonがデフォルトで正しく構築されていないため、このメソッド呼び出しを追加しました。
追加された 著者 eyeballpaul,
ええ、2つのチェックボックスは、チェックボックスを作成するRazorメソッドのためにフォームに出力され、両方の値を追加しています。しかしこれは共通の問題でなければなりません。 Razorによって作成されたチェックボックスをAJAXを通じてサーバーに送信します。
追加された 著者 eyeballpaul,
私は今この問題の解決策を見つけました。そして、私がフォーラムに応答を追加するまで、元の質問を更新しました。
追加された 著者 eyeballpaul,