web-dev-qa-db-ja.com

ビューモデルへのASP.NET MVC 4 JSONバインディング-ネストされたオブジェクトエラー

ビューモデルへのjsonバインディングに問題があります。これが私のコードです:

私のViewModelsの一部(AddressViewModelにはより多くのプロパティがあります):

public class AddressViewModel
{
        [Display(Name = "Address_Town", ResourceType = typeof(Resources.PartyDetails))]
        public string Town { get; set; }

        [Display(Name = "Address_Country", ResourceType = typeof(Resources.PartyDetails))]
        public Country Country { get; set; }
}

public class Country : EntityBase<string>
{
        public string Name { get; set; }

        protected override void Validate()
        {
            if (string.IsNullOrEmpty(Name))
            {
                base.AddBrokenRule(new BusinessRule("CountryName", "Required"));
            }
        }
}

JavaScript:

$(document).on("click", "#addAddress", function () {
            var jsonData = {
                "Town": $('#txt-Town').val(),
                "District": $('#txt-District').val(),
                "Street": $('#txt-Street').val(),
                "PostCode": $('#txt-PostCode').val(),
                "FlatNumber": $('#txt-FlatNumber').val(),
                "PremiseName": $('#txt-PremiseName').val(),
                "PremiseNumber": $('#txt-Premisenumber').val(),
                "Country": {
                    "Name": $('#txt-Country').val(),
                }
            };
            var addressData = JSON.stringify(jsonData);
            $.ajax({
                url: '/Customer/SaveAddress',
                type: "POST",
                dataType: "json",
                contentType: "application/json; charset=utf-8",
                data: addressData,
                success: function (result) {
                    $("#addIndividualAddressDialog").data("kendoWindow").close();
                },
                error: function (result) {
                    alert("Failed");
                }

            });
        });

コントローラーのヘッダー:

[HttpPost]
 public ActionResult SaveAddress(AddressViewModel addressViewModel)

これは私がfirebugで見るものです:

enter image description here

そしてこれは私がVSで見るものです:

enter image description here

ご覧のとおり、プレーンプロパティは正しくバインドされていますが、ネストされたオブジェクト(国)はnullです。私はさまざまな記事をたくさん読みましたが、まだ何が間違っているのかわかりません。お願い助けて!

15
Piotr Czarnecki

問題はアクションメソッドのパラメーターにあります。

_[HttpPost]
public ActionResult SaveAddress(AddressViewModel addressViewModel)
_

JSON.stringify()を使用すると、オブジェクトではなく文字列をコントローラーに送信します。したがって、目標を達成するためにいくつかの作業を行う必要があります。

1)アクションメソッドのパラメーターを変更します。

_[HttpPost]
public ActionResult SaveAddress(string addressViewModel)
_

2)その文字列をオブジェクトに逆シリアル化します。つまり、AddressViewModelです。

_IList<AddressViewModel> modelObj = new 
JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);
_

したがって、最終的なアクションメソッドは次のようになります。

_[HttpPost]
public ActionResult SaveAddress(string addressViewModel)
{
    IList<AddressViewModel> modelObj = new 
    JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);

    // do what you want with your model object ...
}
_
17
Amin Saqi

Jsonのシリアル化を行わなくても、既存のActionMethodをそのまま維持できます。クライアント側で、jsonからオブジェクトを作成します。

JSON.parse(jsonData)

$ .ajaxデータプロパティで送信します。

または、jsonを作成する代わりに、オブジェクトを作成します。

var dataObject = new Object();
dataObject.Town = $('#txt-Town').val();
dataObject.District = $('#txt-District').val();
...

そして、そのオブジェクトを$ .ajaxデータプロパティで送信します。

18
graumanoz

実際には、最良のオプションは単に削除することです

var addressData = JSON.stringify(jsonData);

jsonData自体を並べて送信します。 ASP.NET MVCは、単なる文字列ではなく、実際のオブジェクトである場合、自動バインドします。

オッカムのかみそり

3
Rap

古いスレッドについてお答えできません。ここでは、JsonResultの代わりにActionResultを使用できます。

これはあなたの署名です

 [HttpPost]
 public ActionResult SaveAddress(AddressViewModel addressViewModel)

それは次のようになります

[HttpPost]
 public JsonResult SaveAddress(AddressViewModel addressViewModel)
 {
    return Json(status);
 }

JsonResultの代わりにActionResultを使用すると、Deserializeを使用する必要がないという利点があります。

ここにリンクがあります http://codeforcoffee.org/asp-net-mvc-intro-to-mvc-using-binding-json-objects-to-models/ このリンクから、あなたは得ることができます考え。

2
Thomas

または、JsonConvert.DeserializeObject<>();を使用できます

以下は、JSON.stringify()の結果を逆シリアル化するコードです

IList<AddressViewModel> modelObj = JsonConvert.DeserializeObject<IList<AddressViewModel>>(addressViewModel);

の代わりに

JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);
1
user3559829