如何正确地将json与子对象绑定到ASP.NET MVC ViewModel?

时间:2012-06-12 05:19:55

标签: asp.net-mvc json serialization model-binding

给出以下客户端代码片段:

var vm = {
  Input : "Label: Value",
  Rules : [
    { Name : "RemoveString",
      Params : [
        "Label: "
      ]
    }
  ]
};

$.post("/API/ApplyRule", vm, function(data) { });

服务器端的以下ViewModel:

[Serializable]
public class ApplyRuleRequestViewModel
{
    public string Input { get; set; }
    public List<RuleViewModel> Rules { get; set; }
}

[Serializable]
public class RuleViewModel
{
    public string Name { get; set; }
    public List<string> Params { get; set; }
}

以下控制器代码:

public class APIController : Controller
{
    [HttpPost]
    public ActionResult ApplyRule(ApplyRuleRequestViewModel model)
    {
        //Problem here... model is not fully deserialized into the ViewModel object.
        return View();
    }
}

我在尝试序列化客户端ViewModel的Rules部分时遇到问题。当在上面的//问题...上面的控制器行调试代码时,我看到顶级对象属性创建它,而不是子对象。所以,我得到类似的东西:

var vm = new ApplyRuleRequestViewModel {
  Input = "Label: Value",
  Rules = new List<RuleViewModel> {
     new RuleViewModel { Name = null, Parameters = null }
  }
}

我期待的是:

var vm = new ApplyRuleRequestViewModel {
  Input = "Label: Value",
  Rules = new List<RuleViewModel> {
     new RuleViewModel { 
         Name = "RemoveString", 
         Parameters = new List<string> { "Label: " }
     }
  }
}

我在这里做错了什么? 为什么它没有正确绑定Rules数组?

您是否需要创建自己的自定义模型绑定器才能正确绑定?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:1)

您可以将信息作为JSON发送。

var vm = {
  Input : "Label: Value",
  Rules : [
    { Name : "RemoveString",
      Params : [
        "Label: "
      ]
    }
  ]
};

$.postJson("/API/ApplyRule", vm, function(data) { }); // See below for definition of `.postJson`.

最后一个参数json将设置接受标头以指示需要JSON。默认模型绑定器应自动与内置JsonValueProviderFactory交互以正确读取结构化消息。

编辑错过了什么。您需要设置contentType,因此.post可能不起作用。

这是一个发布JSON的辅助方法(不仅仅是POSTING和接收 json,就像帖子一样)。

$.postJson = function(url, data, success) {
  $.ajax({
            url: url,
            type: 'POST',
            dataType: 'json',
            data: JSON.stringify(data),
            contentType: 'application/json; charset=utf-8',
            success: success
        }); 
}