0

JSONペイロードを介してajaxpostリクエストでリストデータを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ペイロードです。

私はこれに頭を悩ませてきましたが、経費項目が拘束されない理由について明確な理由がわかりません。

アイデア/提案はありますか?

4

2 に答える 2

1

インターフェイスにバインドすることはできません。リストとIListを使用する:

private List<ExpenseApiModel> _expenses = new List<ExpenseApiModel>();
public List<ExpenseApiModel> expenses { get { return _expenses; } set { _expenses = value; } }
于 2013-01-11T17:07:29.153 に答える
0

MVC4 モデル バインディングで、あなたと非常によく似た問題が発生しました。解決策はありますが、モデル バインダーのソースにアクセスできないため、答えを推測することしかできません。おそらく、問題の解決策は、「expensesComplete」と「expensesTotal」の名前を「expenses」で始まらない別の名前に変更することです。

私のモデル (はい、インターフェイスにバインドできます。IEnumerable をリストまたは配列に置き換えても違いはありません。モデル バインダーは実際にはここにリストを貼り付けるだけです) & アクションは、最も単純な形式に取り除かれます:

[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}]}

インシデント.Inv は null になります。

多くの紛らわしい副作用がありましたが、Inv で始まらないように IncidentDetails モデルの InvDisp プロパティの名前を変更すると、問題が解決することがわかりました。

モデル内で InvDisp の名前を InxDisp に変更した次の JSON は、incident.Inv の 1 つの要素のリストになりました。

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

紛らわしい副作用の例としては、IncidentDetails クラスから ChangeDetails プロパティを削除し、いくつかのプロパティを InvolvedPartyDetails クラスに追加すると、突然機能し始めることがあります。たとえば、次の JSON では、1 つのアイテムでインシデント.Inv が返されます。

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

ただし、InvolvedPartyDetails のいずれかのプロパティを削除するか、ChangeDetails を元に戻すと、再びバインディングが妨げられます。同様に、配列内の複数の InvolvedPartyDetails を送信すると、他のプロパティが存在するかどうかに応じて動作する場合があります。

ただし、唯一の堅牢なソリューションはネーミングです。

于 2013-12-17T15:41:48.513 に答える