2015-02-10 2 views
0

У меня есть время с этим. Я должен что-то упустить..Net Модель привязки набора данных через пост JSON

Я отправляю сложную модель через Angular/JSON в контроллер .NET. При отправке обратно на сервер DefaultModelBinder только частично привязывается к модели (простые значения, такие как int (ID) и строка (заголовок), являются точными). Кажется, что набор данных «ListItems» игнорируется, а также данные «ProductList», которые являются частью модели ProjectDetails. Из того, что я читаю, для сложных объектов 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 не содержит таблиц, а DataList, который содержится в наборе данных ListItems, не существует.

ПРИМЕЧАНИЕ. Данные ProjectStatusCodes в JSON не сопоставляются с моделью, поскольку она использовалась только для целей отображения в форме.

+0

Являются ли сложные объекты связанными с элементом управления в форме, которую вы публикуете, это мой первый вопрос? Во-вторых, вы прочитали эту статью и попытались использовать Списки <>? http://stackoverflow.com/questions/20554971/mvc-form-model-returning-null-for-complex-object-collection –

+0

@Bill Спасибо за комментарий. Это проект MVC, поэтому нет связанных контроллеров или веб-форм aspx. Я добавил шаблон Angular HTML с полями формы для уточнения. Я прочитал статью о подходе к списку. Что вы предложите для перезаписи модели? – redoc

+0

Да, я знаю, что это mvc. По вашему мнению, в вашей форме вы должны иметь свои свойства модели, связанные с чем-то в вашей форме, чтобы сами данные «зависали» во время сообщения формы. Для вашей модели переписать вместо использования набора данных и данных, я бы создал фактический класс. Итак, это будет что-то вроде свойства List и списка свойств .......... Тогда на стороне сервера у вас будет класс для LstItem со своими свойствами и классом для LstProduct. –

ответ

0

OK. Я понял. Кажется, что JSON.NET отлично справляется с сериализацией объекта при отправке, убедившись, что он полностью совместим с JSON. Плохая новость заключается в том, что он удаляет большинство вещей, которые делают datatable de-serializable при отправке его обратно в приложение .NET.

Что я на самом деле делал, это ловить строку JSON после обратной передачи и получать доступ к сериализованным данным datatable отдельно, используя сериализацию фрагмента 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() 

КОД распарсить 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

0

Если он пытается сериализовать «ListItems» из вашего JSON в объект списка, это может вызвать проблемы, потому что вы не имеете скобки в вашем 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" 
     } 
    ]} 
Смежные вопросы