ASP.NET MVC 4 JSON绑定到视图模型 - 嵌套对象错误

Pio*_*cki 14 json model-binding asp.net-mvc-4

我遇到了json绑定到视图模型的问题.这是我的代码:

我的ViewModel的一部分(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"));
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

使用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");
                }

            });
        });
Run Code Online (Sandbox Code Playgroud)

控制器头:

[HttpPost]
 public ActionResult SaveAddress(AddressViewModel addressViewModel)
Run Code Online (Sandbox Code Playgroud)

这是我用firebug看到的:

在此输入图像描述

这就是我在VS中看到的:

在此输入图像描述

如您所见,Plain属性绑定正确,但我的嵌套对象(Country)为null.我读了很多不同的文章,但我仍然不知道我做错了什么.请帮帮我!

gra*_*noz 19

您可以保持现有的ActionMethod不受json序列化的影响:在客户端,从json创建一个对象:

JSON.parse(jsonData)
Run Code Online (Sandbox Code Playgroud)

并在$ .ajax数据属性中发送它.

或者,不是创建json,而是创建一个对象:

var dataObject = new Object();
dataObject.Town = $('#txt-Town').val();
dataObject.District = $('#txt-District').val();
...
Run Code Online (Sandbox Code Playgroud)

再次,在$ .ajax数据属性中发送该对象.

  • 这是这个问题的正确答案.无需修改服务器端代码,只需从客户端发送正确的对象类型即可. (4认同)

Ami*_*aqi 18

问题来自您的操作方法参数:

[HttpPost]
public ActionResult SaveAddress(AddressViewModel addressViewModel)
Run Code Online (Sandbox Code Playgroud)

在使用时JSON.stringify(),您将字符串发送到控制器,而不是对象!所以,你需要做一些工作来实现你的目标:

1)更改您的操作方法参数:

[HttpPost]
public ActionResult SaveAddress(string addressViewModel)
Run Code Online (Sandbox Code Playgroud)

2)将该字符串反序列化为一个对象 - 即AddressViewModel:

IList<AddressViewModel> modelObj = new 
JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);
Run Code Online (Sandbox Code Playgroud)

因此,您的最终操作方法应如下所示:

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

    // do what you want with your model object ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个惯用的解决方案,因为它将绕过MVC的验证和绑定功能.一个更好的解决方案是添加一个JsonModelBinder并将这个反序列化逻辑放在那里.如果可以通过覆盖DefaultModelBinder中的一些方法来完成 (8认同)