2015-02-10 77 views
0

我對此有一段時間了。我肯定錯過了什麼。.Net通過JSON綁定數據集的模型

我通過Angular/JSON發佈一個複雜的模型到.NET控制器。將它發回服務器時,DefaultModelBinder只能部分綁定到模型(簡單的值如int(ID)和string(title))。 「ListItems」數據集似乎被忽略,以及作爲ProjectDetails模型一部分的「ProductsList」數據表。從我正在閱讀的內容來看,對於複雜的對象,DefaultModelBinder會遞歸地在JSON中進行第二次傳遞,然後映射它可以找到的對象。我嘗試了很多通過搜索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崗位工作網絡ne連接到控制器,並綁定ImageID和Title。 ListItems數據集不包含任何表,並且ListItems數據集中的ProductsList數據表不存在。

注意:JSON中的ProjectStatusCodes數據未映射回模型,因爲它僅用於表單上的顯示目的。

+0

複雜的對象綁定到您發佈的表單中的控件是我的第一個問題嗎?其次,您是否閱讀過這篇文章並嘗試使用Lists <>? http://stackoverflow.com/questions/20554971/mvc-form-model-returning-null-for-complex-object-collection – 2015-02-11 00:45:11

+0

@Bill感謝您的評論。這是一個MVC項目,所以沒有綁定的控制器或aspx webforms。我添加了帶有表單字段的Angular HTML模板以進行說明。我閱讀了關於列表方法的文章。對於重寫模型,你會有什麼建議? – redoc 2015-02-11 02:42:55

+0

是的,我知道這是mvc。在您的表單中,您必須將模型屬性綁定到表單中的某些內容,以便數據本身在表單發佈期間「堅持」。爲了您的模型重寫,而不是使用數據集和數據表,我會創建一個實際的類。因此,這將是類似於屬性列表和屬性列表..........然後在服務器端,您將擁有一個LstItem的類,其屬性和一個LstProduct的類。 – 2015-02-11 23:25:18

回答

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() 

代碼來解析IT OUT和反序列化

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

    Console.Write(results) 

不是非常優雅,但它的工作原理。

+0

有關使用JSON減少序列化數據表大小的更多信息http://mvitorino.com/2011/05/28/json-net-custom-datatable-serializerconverter/ – redoc 2015-03-01 20:15:03

0

如果它試圖從你的JSON序列化「listItems中的」成一個列表對象,則可能會導致問題,因爲你沒有括號中的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" 
     } 
    ]} 
確定。