3

最近、アプリケーションを MVC3 から MVC4 に更新しました。MVC4では、ViewModel にStudioStudioExecutiveのようなプロパティ名があると、投稿時に問題が発生することがわかりました。コントローラ メソッドでは、いつデータが入力されるかを常に取得Studio = nullStudioExecutiveます。

これは私たちの問題の例であり、この問題に対する答えがあることを願っています.

データ クラス:

public class TestContact
{

    public List<TestContactItem> Studio { get; set; }
    public List<TestContactItem> StudioExecutive { get; set; }

    public TestContact()
    {
        Studio = new List<TestContactItem>();
        StudioExecutive = new List<TestContactItem>();
    }
}

public class TestContactItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

コントローラーの方法:

public ActionResult TestContactView()
{
    var vm = new TestContact();
    vm.Studio.Add(new TestContactItem(){Id=1, Name = "Studio Contact ID=1"});
    vm.StudioExecutive.Add(new TestContactItem() { Id = 2, Name = "Studio Exec Contact ID=2" });
    return View(vm);
 }

[HttpPost]
public ActionResult SaveTestContact(TestContact model)
{
    return Content("success");
}

View / Ajax POST を使用した JavaScript:

@using System.Web.Script.Serialization
@model TestContact

<button type="button" onclick="SaveTestContact();">Click Here to Post</button>

<script type="text/javascript">

    $(document).ready(function() {
         globalTestModel = @Html.Raw(new JavaScriptSerializer().Serialize(Model));
    });

    function SaveTestContact() {
        // passing additional studio & studio executive parameter to controller because it was not mapping correctly to the server side viewmodel without it
        $.ajax({
            type: "POST",
            url: "/Test/SaveTestContact",
            data: JSON.stringify(globalTestModel),
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function (msg) {

            }
        });
    }
</script>

この例では、オブジェクトに少なくとも 1 つと 1StudioStudioExecutiveを入力し、ビューをレンダリングします。ビューのボタンをクリックすると、同じオブジェクトがコントローラー メソッドに POST されますが、ViewModel が正しくバインドされず、Studioプロパティが null に設定されます。

*残念ながら画像を投稿できません。Studioカウントが 0 でStudioExecutiveカウントが 1であることを示すオブジェクトのスクリーンショットがあります。

POST の前にブレークポイントを配置して、JavaScript のシリアル化が正しく、オブジェクトが読み込まれたことを確認しました。

これは、一方が他方の部分文字列である 2 つのプロパティの命名規則に関係していると結論付けました。同じ問題に遭遇し、私たちを正しい方向に向けることができる人.

4

1 に答える 1

1

これが質問に対する「完全な答え」ではないことはわかっていますが、これにより問題に対する追加の洞察が得られ、最終的に「完全な解決策」につながると思います。

OP の例に示されているように、 フィールドStudioとフィールドのそれぞれに 1 つのアイテムがあるとします。StudioExecutivejs

globalTestModel = '@Html.Raw(new JavaScriptSerializer().Serialize(Model))';

$.ajax({
    type: "POST",
    url: "/Test/SaveTestContact",
    data: JSON.stringify(globalTestModel),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function (msg) {

    }
});

StudioExecutiveコントローラー メソッドは、既に述べたように受け取るだけです。同じことを行い、以下に示すように js でオブジェクトをビルドすると、同じ結果が得られます。

o = {
    Studio: [{
        Id: 1,
        Name: 'Studio Contact ID=1',
    }],
    StudioExecutive: [{
        Id: 2,
        Name: 'Studio Exec Contact ID=2',
    }]            
};
$.ajax({
    type: "POST",
    url: "/Test/SaveTestContact",
    data: JSON.stringify(o),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function (msg) {

    }
});

ここからが興味深い部分です。フィールドに別の項目を追加しStudioて同じ方法で投稿すると、同じ結果が得られます。

// Do this in the controller and do the same ajax post
public ActionResult TestContactView()
{
    var vm = new TestContact();
    vm.Studio.Add(new TestContactItem(){Id=1, Name = "Studio Contact ID=1"});
    vm.Studio.Add(new TestContactItem(){Id=3, Name = "Studio Contact ID=3"});
    vm.StudioExecutive.Add(new TestContactItem() { Id = 2, Name = "Studio Exec Contact ID=2" });
    return View(vm);
 }

jsしかし、以下に示すようにオブジェクトをビルドすると、コントローラーはStudio2StudioExecutiveつのアイテムを持つ と 1 つのアイテムを持つ の両方を受け取ります。

o = {
    Studio: [{
        Id: 1,
        Name: 'Studio Contact ID=1',
    },
    {
        Id: 2,
        Name: 'Studio Contact ID=2',
    }],
    StudioExecutive: [{
        Id: 2,
        Name: 'Studio Exec Contact ID=2',
    }]            
};
// then do the ajax post

それで、私たちは何を学びましたか

これは、次の 2 つのことを示しています。

  1. デフォルトのモデル バインダーには、同じ名前で始まる 2 つ以上のフィールドをバインドできないという問題があります。
  2. JSON.stringify項目が 1 つしかない場合も実行できませんが、フィールドに名前が最も短い項目が複数ある場合は実行できます (例:Studio )
于 2013-04-18T03:26:46.413 に答える