0

私はこれでかなりの時間を過ごしています。私は何かが欠けているに違いない。

Angular/JSON 経由で複雑なモデルを .NET コントローラーに投稿しています。サーバーにポストバックするとき、DefaultModelBinder はモデルに部分的にのみバインドします (int (ID) や string (タイトル) などの単純な値は問題ありません)。「ListItems」データセットは、ProjectDetails モデルの一部である「ProductsList」データテーブルと同様に無視されているようです。私が読んでいることから、複雑なオブジェクトの場合、DefaultModelBinder は JSON で 2 回目のパスを再帰的に取得し、見つけたオブジェクトをマップします。StackOverflow を検索して見つけた多くの解決策を試しましたが、役に立ちませんでした。この時点で、私はちょうど私の視点を失ったと思います。これが私が持っているものです。どんな助けでも大歓迎です。

モデル

    Public Class ProjectDetails

    Private _ListItems As DataSet
    <JsonProperty("ListItems")> _
    Public Property ListItems() As DataSet
        Get
            Return _ListItems
        End Get
        Set(ByVal value As DataSet)
            _ListItems = value
        End Set
    End Property

    Private _ProductsList As DataTable
    Public Property ProductsList As DataTable
        Get
            Return _ProductsList
        End Get
        Set(value As DataTable)
            _ProductsList = value
        End Set
    End Property

    Private _imageID As Int32 = 0
    Public Property imageID() As Int32
        Get
            Return _imageID
        End Get
        Set(ByVal value As Int32)
            _imageID = value
        End Set
    End Property

    Private _Title As String = String.Empty
    Public Property Title() As String
        Get
            Return _Title
        End Get
        Set(ByVal value As String)
            _Title = value
        End Set
    End Property
    End Class

アクションコントローラー

    <Authorize()> _
    <AcceptVerbs(HttpVerbs.Post)> _
    <ValidateInput(False)> _
    Async Function ProjectUpdate(ByVal d As ProjectDetails) As Task(Of JsonResult)
    'send results to database here
    Save(d)
    return json(true)
    End Function

ヘッダ

    POST http://localhost:51110/projectUpdate HTTP/1.1
    Host: localhost:51110
    Connection: keep-alive
    Content-Length: 10119
    Accept: application/json, text/plain, */*
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.111 Safari/537.36
    Content-Type: application/json;charset=UTF-8
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.8

投稿されたJSONデータ

    {"ListItems":

    {"ProjectStatusCodes":[{"id":1,"ProjectStatusTx":"Stage1 - Under Construction"},{"id":3,"ProjectStatusTx":"Stage3 - Project Released"},{"id":4,"ProjectStatusTx":"Project Closed"}],

    "ProductsList":[
    {"id":2336,"Name":"Product1","Description":"This is a description","$$hashKey":"00K"},
    {"id":2337,"Name":"Product2","Description":"This is a second description","$$hashKey":"00M"}],

    "imageID":345,
    "Title":"books", }
    }

AngularJS コード

    $scope.update = function (formData) {
    $http({
        method: 'POST',
        url: '/projectbuilder/projectUpdate',
       contentType: 'application/json; charset=utf-8',
        data: JSON.stringify($scope.formData)
    }).success(function (data, status, headers, config) {
        $scope.codeStatus = status;
    }).error(function (data, status, headers, config) {
        $scope.codeStatus = status || "Request failed";

    });

フォーム値を含む HTML テンプレート

    <div ng-repeat="ProductsList in formData.ListItems.ProductsList">
        <div>
          <div>
            <div>
               <input value="{{ProductsList.Title}}" name="ProductsList.Title" ID="ProductsList.Title" ng-model="ProductsList.Title" >
               <br />
               <input value="{{ProductsList.ImageID}}" name="ProductsList.ImageID" ID="ProductsList.ImageID" ng-model="ProductsList.ImageID" >
            </div>
         </div>
    </div>

動作 JSON ポストはコントローラーに対して正常に機能し、ImageID と Title をバインドします。ListItems データセットにはテーブルが含まれておらず、ListItems データセット内の ProductsList データテーブルは存在しません。

注: JSON の ProjectStatusCodes データは、フォームに表示する目的でのみ使用されたため、モデルにマッピングされません。

4

2 に答える 2

0

"ListItems" を json からリスト オブジェクトにシリアル化しようとしている場合、リスト内のオブジェクトが 1 つだけであっても、json にブラケットがないため、問題が発生する可能性があります。

  {"ListItems":[ 
         {
             "ProjectStatusCodes":[{"id":1,"ProjectStatusTx":"Stage1 - Under Construction"},{"id":3,"ProjectStatusTx":"Stage3 - Project Released"},{"id":4,"ProjectStatusTx":"Project Closed"}],
             "ProductsList":[{"id":2336,"Name":"Product1","Description":"This is a description","$$hashKey":"00K"},{"id":2337,"Name":"Product2","Description":"This is a second description","$$hashKey":"00M"}],
             "imageID":345,
             "Title":"books"
         } 
  ]}
于 2015-02-24T22:34:06.590 に答える
0

わかった。私はそれを考え出した。JSON.NET は、オブジェクトが JSON に完全に準拠していることを確認して送信するときに、オブジェクトをシリアル化するという素晴らしい仕事をしているようです。悪いニュースは、データ テーブルを .NET アプリケーションに送り返すときに、データ テーブルを逆シリアル化可能にするほとんどの要素が削除されることです。

私が最終的にやったのは、ポストバックで JSON 文字列をキャッチし、ここで見つけることができる JSON.NET フラグメントのシリアル化を使用して、シリアル化されたデータテーブル データに個別にアクセスすることでした。http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm オブジェクトの残りを「そのまま」にして、JSON 文字列からデータテーブルを取得し、この手法を使用して手動で逆シリアル化を行いました。記事の例は非常に有益でした。

JSON 文字列を読み取るコード

    Dim req As Stream = Request.InputStream
    req.Seek(0, System.IO.SeekOrigin.Begin)
    Dim jsonstring As String = New StreamReader(req).ReadToEnd()

解析してデシリアライズするコード

    Dim ProductsList As JObject = JObject.Parse(jsonstring)
    Dim results As IList(Of JToken) = ProductsList("ListItems")("ProductsList").Children().ToList()

    Console.Write(results)

それほどエレガントではありませんが、機能します。

于 2015-03-01T20:10:59.430 に答える