MVC4问题绑定List通过AJAX发送到控制器模型

时间:2013-01-11 15:40:41

标签: ajax json asp.net-mvc-4

我一直遇到一个奇怪的绑定问题,试图通过JSON有效负载将列表数据发送到ajax post请求中的MVC4控制器。

我们发送的有效负载是

{
   "assignmentId":"AssignmentId2",
   "shiftId":null,
   "startDate":null,
   "startTime":{
      "hours":0,
      "minutes":0
   },
   "endTime":{
      "hours":0,
      "minutes":0
   },
   "breaksDuration":{
      "hours":0,
      "minutes":0
   },
   "authorised":false,
   "authorisedName":null,
   "mileageDescription":null,
   "mileage":0,
   "expenses":[
      {
         "description":"DADADDAADADADAD",
         "total":"5"
      }
   ],
   "billableDuration":{
      "hours":0,
      "minutes":0
   },
   "expensesComplete":true,
   "expensesTotal":5
}

费用清单项目未绑定到以下模型结构

public class ShiftApiModel
    {
        public string assignmentId { get; set; }
        public string shiftId { get; set; }
        [Required]
        public DateTime startDate { get; set; }
        [Required]
        public ShortTimeSpan startTime { get; set; }
        [Required]
        public ShortTimeSpan endTime { get; set; }
        public bool authorised { get; set; }
        public string authorisedName { get; set; }
        public ShortTimeSpan breaksDuration { get; set; }
        public decimal mileage { get; set; }
        public string mileageDescription { get; set; }

        private IList<ExpenseApiModel> _expenses = new List<ExpenseApiModel>();
        public IList<ExpenseApiModel> expenses { get { return _expenses; } set { _expenses = value; } }
    }

public class ExpenseApiModel
{
    public string description { get; set; }
    public double total { get; set; }
}

实际的ajax请求如下:

 $.ajax({
    type: type,
    url: serviceUrl,
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: (props.data) ? props.data : null,
    success: function (jqXHR, textStatus) {
    this.serviceCallComplete(jqXHR, props.complete, props.error);
    }.bind(this),
    error: function (jqXHR, textStatus, errorThrown) {
    this.serviceCallFailure(jqXHR, props.error);
    }.bind(this)
});

其中props.data是上述JSON有效负载。

我一直在摸不着头脑,看不出任何明显的原因,为什么费用项目不会受到限制。

有任何想法/建议吗?

2 个答案:

答案 0 :(得分:1)

您无法绑定到界面。使用List与IList:

private List<ExpenseApiModel> _expenses = new List<ExpenseApiModel>();
public List<ExpenseApiModel> expenses { get { return _expenses; } set { _expenses = value; } }

答案 1 :(得分:0)

我遇到了与MVC4模型绑定非常类似的问题。我有一个解决方案,但无法访问模型绑定源,我只能推测答案。您的问题的解决方案可能是将“expensesComplete”和“expensesTotal”的名称更改为不以“费用”开头的其他内容。

我的模型(是的,你可以绑定到一个接口,用列表或数组替换IEnumerable没有区别,我看到模型绑定器实际上只是在这里粘贴一个List)&amp;行动被剥夺了最近的形式:

[Serializable]
public class InvolvedPartyDetails
{
    public long? Key { get; set; }
}

[Serializable]
public class IncidentDetails
{
    public long IncidentNo { get; set; }
    public string InvDisp { get; set; }
    public string ChangeDetails { get; set; }
    public IEnumerable<InvolvedPartyDetails> Inv { get; set; }
}

[HttpPost]
public ActionResult SubmitData(IncidentDetails incident)
{
...

如果我提交以下JSON(信息中包含的标题,将从此处开始)。为了清晰起见,JSON也放了多行:

POST http://johnapi.com/AngularTest/SubmitData HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://johnapi.com/AngularTest/MVCCrazy/
Accept-Language: en-GB,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; MDDCJS; rv:11.0) like Gecko
Host: johnapi.com
Content-Length: 72
DNT: 1
Connection: Keep-Alive
Pragma: no-cache

{"IncidentNo":0,
"InvDisp":"Boo",
"ChangeDetails":"COD",
"Inv":[{"Key":0}]}

incident.Inv将为null。

虽然有许多令人困惑的副作用,但我发现在IncidentDetails模型中重新命名InvDisp属性以便不以Inv开头解决问题。

以下JSON,InvDisp在模型中重命名为InxDisp,导致出现了一个1个元素的事件列表.Inv:

{"IncidentNo":0,
"InxDisp":"Boo",
"ChangeDetails":"COD",
"Inv":[{"Key":0}]}

混淆副作用的一个例子是我可以从IncidentDetails类中删除ChangeDetails属性,并向InvolvedPartyDetails类添加一些属性,它会突然开始工作,例如以下JSON会给我一个fact.Inv与一个项目:

{"IncidentNo":0,
"InvDisp":"Boo",
"Inv":[{"LinkType":null,"Key":0,"Name":null}]} 

但是删除InvolvedPartyDetails中的任何一个属性或者放回ChangeDetails会再次阻止绑定,同样,有时在数组中发送多个InvolvedPartyDetails会导致一些工作,这取决于存在的其他属性。

然而,单一的强大解决方案是命名。