2016-05-19 7 views
2

Angularを使用して、合理的に複雑なデータモデルをWeb APIコントローラに配置する際に問題があります。角度Web APIのPUTモデルが認識されない

は、ここでは、これまで持っているものです。

角度コントローラー:

$scope.saveDelivery = function() { 
    var val = $('#run-value', $element)[0].value; 
    console.info("Batsman: " + $scope.striker.Name + ", Shot: " + $scope.shot + " for " + val + " runs. "); 

    if ($scope.game.Overs[$scope.over - 1].Deliveries == null) { 
     $scope.game.Overs[$scope.over - 1].Deliveries = []; 
    } 

    console.info("Over: " + $scope.over + ", Delivery: " + $scope.delivery); 
    if ($scope.delivery > 6) { 
     $scope.over++; 
     $scope.delivery = 1; 
    } 
    else { 
     $scope.delivery++; 
    } 

    if ($scope.striker == undefined) { 
     alert("No batsman selected"); 
    } 
    else { 

     var shot = {}; 

     shot.Id = 0; 
     shot.Runs = $scope.runs; 
     shot.Stroke = $scope.shot; 
     if ($scope.runs == -5) { 
      shot.Dismissal = $scope.shot; 
     } 
     else { 
      shot.Dismissal = null; 
     } 

     var delivery = {}; 
     delivery.Id = 0; 
     delivery.Number = $scope.delivery; 
     delivery.Batter = $scope.striker; 
     delivery.Bowler = $scope.nonstriker; 
     delivery.Shot = shot; 


     $scope.game.Overs[$scope.over - 1].Deliveries.push(delivery); 
     console.info($scope.game); 

     $http.put('/api/games/:id', { id: $scope.game.Id, game: $scope.game }).success(function (data, status, headers, config) { 
      console.info(data); 
     }); 
     //$http.post('/score/testing', { Test: "This is a test" }).success(function (data, status, headers, config) { 
     // console.info(data); 
     //}); 
    } 
} 

APIコントローラ:

// PUT: api/Games/5 
[HttpPut("{id}")] 
public IActionResult PutGame(int id, [FromBody] Game game) 
{ 
    if (!ModelState.IsValid) 
    { 
     return HttpBadRequest(ModelState); 
    } 
    ... etc... 

私はフィドラーでつかんだ生のJSONデータは申し訳ありません(このようになります書式設定の場合):

{"id":1,"game":{"Id":1,"Date":"2016-04-20T20:30:00","Team":{"Id":"a5abca2a-0e05-11e6-8596-4f0c9eb370be","Name":"Yellow Duckies","Players":null},"Opposition":"Miller Studios","Overs":[{"Id":1,"Number":1,"Innings":0,"Deliveries":[{"Id":0,"Number":2,"Batter":{"Id":"1a903e4a-0f8a-11e6-99ad-b3c19db370be","Email":"[email protected]","Name":"Phil"},"Bowler":{},"Shot":{"Id":0,"Runs":2,"Stroke":2,"Dismissal":null}}]},{"Id":2,"Number":2,"Innings":0,"Deliveries":null},{"Id":3,"Number":3,"Innings":0,"Deliveries":null},{"Id":4,"Number":4,"Innings":0,"Deliveries":null},... 

Web APIのPUTパラメータを平文objectに変更すると、本体がきれいに拾われるため、オブジェクトの解析方法に問題があると推測していますが、問題が起きる。ここにC#モデルがあります:

namespace IndoorCricket.Models 
{ 
    public enum Innings { Batting, Bowling } 

    public class Game 
    { 
     public int Id { get; set; } 
     public DateTime Date { get; set; } 
     public virtual Team Team { get; set; } 
     public string Opposition { get; set; } 

     public virtual ICollection<Over> Overs { get; set; } 
    } 


    public class Over 
    { 
     public int Id { get; set; } 
     public int Number { get; set; } 
     public Innings Innings { get; set; } 

     //public virtual Game Game { get; set; } 
     public virtual ICollection<Delivery> Deliveries { get; set; } 
    } 

    public class Delivery 
    { 
     public int Id { get; set; } 
     public int Number { get; set; } 
     public virtual Shot Shot { get; set; } 

     public virtual Player Bowler { get; set; } 
     public virtual Player Batter { get; set; } 
    } 

    public class Shot 
    { 
     public int Id { get; set; } 
     public int Runs { get; set; } 
     public Stroke Stroke { get; set; } 
     public Dismissal Dismissal { get; set; } 
    } 

    public enum Stroke 
    { 
     Out  = -5, 
     Dotball = 0, 
     Single = 1, 
     Two  = 2, 
     Three = 3, 
     Four = 4, 
     Five = 5, 
     Seven = 7 
    } 

    [Flags] 
    public enum Dismissal 
    { 
     Caught = 1, 
     Bowled = 2, 
     Runout = 4, 
     Stumped = 8, 
     Mankad = 16, 
     LBW  = 32 
    } 
} 

誰もが問題を見つけることができるより良い目を持っていますか?

+0

...と、かなりラフなコードを事前に謝罪。後でクリーンアップする必要のあるデバッグ/テスト用のものがたくさんあります。 –

+0

すばやく試してみることはできますか? $ http.put( '/ api/games /' + $ scope.game.Id、{game:$ scope.game})。suc ... –

+0

@EduardUta IDは引き続き正常に選択されますが、ゲームパラメータはまだですヌル値が設定されています。効果的には、そのパラメータは新しく初期化されたオブジェクトと同じです。すべてのint値のゼロ、子コレクションのnull –

答えて

0

APIパラメータ型を強く型付けされた "Game"オブジェクトからバニラobjectに変更することで、最終的に問題は解決しました。そこから、JSON.Netを使ってオブジェクトをデシリアライズし、何が送られてきたのかを調べます。

ネストされたJSONオブジェクトに妥当な程度の深さがあったため、値を期待していたプロパティが代わりにnullを渡していたことがわかりました。

私は(それが不快に感じていると私はさらにを通じてこれを仕事をしたいでしょうが)、当分の間、このようにそれを残してきた:

public IActionResult PutGame(int id, [FromBody] object game) 
    { 
     JObject obj = JsonConvert.DeserializeObject<JObject>(game.ToString()); 
     Game g = obj.Root.First.Value<JToken>().First.ToObject<Game>(); 
    ... 
0

ボディから構築しようとしているクラスgameはルートオブジェクトではありません。 .NETはid列を検出し、クラスGameにマップすることはできません。あなたはJSONのルートにgameを作ることができますか?とにかくAPIのコントローラエンドポイントに "id"を渡しているようだから?

さらに、TeamPlayerクラスは指定されていますか?

+0

私は '[HttpPut]'の装飾と実際のメソッドを '' public IActionResult PutGame([FromBody] Game game) ''という単純なゲームメソッドに変更しようとしましたが、これは違いはありません。とにかく、.Netがルート内のIDを認識し、別の引数がボディに渡されることが予想されます。 –

関連する問題