Отправить массив объектов через JSON в ASP.Net MVC3
Я ищу решение для размещения массива объектов в MVC3 через JSON.
пример кода, над которым я работаю:
http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx
JS:
var data = { ItemList: [ {Str: 'hi', Enabled: true} ], X: 1, Y: 2 };
$.ajax({
url: '/list/save',
data: JSON.stringify(data),
success: success,
error: error,
type: 'POST',
contentType: 'application/json, charset=utf-8',
dataType: 'json'
});
ListViewModel.cs:
public class ListViewModel
{
public List<ItemViewModel> ItemList { get; set; }
public float X { get; set; }
public float Y { get; set; }
}
ItemViewModel.cs:
public class ItemViewModel
{
public string Str; // originally posted with: { get; set; }
public bool Enabled; // originally posted with: { get; set; }
}
ListController.cs:
public ActionResult Save(ListViewModel list)
{
// Do something
}
результат этого поста:
список установлен, в a ListViewModel
Его свойства X и Y установлены
Базовое свойство ItemList имеет значение
ItemList содержит один элемент, как и должно
Элемент в этом списке элементов является неинициализированным. Str имеет значение null, а Enabled-false.
другими словами, это то, что я получаю от привязки модели MVC3:
list.X == 1
list.Y == 2
list.ItemList != null
list.ItemList.Count == 1
list.ItemList[0] != null
list.ItemList[0].Str == null
похоже, что MVC3 JsonValueProvider не работает для сложных объектов. Как мне заставить это работать? Нужно ли мне изменять существующий MVC3 JsonValueProvider и исправить это? Если да, то как мне добраться до него и заменить его в проекте MVC3?
связанные с StackOverflow вопросы, которые я уже преследовал безрезультатно:
Asp.net MVC Ajax Json (post Array)
Использует mvc2 и более старое кодирование на основе формы-этот подход не работает с объектом, который содержит массив объектов (JQuery не может правильно его кодировать).
разместить массив сложных объектов с помощью JSON, JQuery в ASP.NET контроллер MVC
Использует Хак, которого я хотел бы избежать где контроллер вместо этого получает простую строку, которую он затем вручную десериализует сам, а не использует фреймворк.
MVC3 RC2 JSON Post Binding не работает правильно
У него не было своего набора типов контента-он установлен в моем коде.
как разместить массив сложных объектов с помощью JSON, jQuery в ASP.NET контроллер MVC?
Этот бедный парень должен был написать JsonFilter только для разбора массива. Другого взлома я бы предпочел избежать.
Итак, как мне это сделать случилось?
6 ответов:
кроме
{ get; set; }, вот некоторые из условий поддержки привязки JSON:
- Это новая функция в ASP.NET MVC 3 (см. "улучшения JavaScript и AJAX").
- строки объекта JSON (’X‘,’ Y‘,’ Str ‘и’ Enabled') должны соответствовать свойствам объекта ViewModel.
- свойства объекта ViewModel должны иметь
{ get; set; }метод.- необходимо указать тип контента как "application / json" в поле запрос.
- если он все еще не работает, проверьте строку JSON, чтобы убедиться, что она действительна.
подробнее на мой пост.
надеюсь, что это поможет!
проблема заключалась в том, что свойства в моделях, которые были в списке, не имели get/set для их общих свойств. Другими словами, автоматическая привязка JSON MVC3 работает только со свойствами объекта, которые имеют get и set.
это не связывает:
public string Str;Это позволит связать:
public string Str { get; set; }
Это странно. Я не могу воспроизвести поведение. Вот моя настройка (ASP.NET MVC 3 RTM):
модель:
public class ItemViewModel { public string Str { get; set; } public bool Enabled { get; set; } } public class ListViewModel { public List<ItemViewModel> ItemList { get; set; } public float X { get; set; } public float Y { get; set; } }
у меня была аналогичная проблема, и обнаружил, что для сложного объекта, числовые значения были пропущены. Они приходили как нули. то есть
var person = { Name: "john", Age: 9 }была получена путем контроллера MVC в качестве объекта человека, где свойства были заселены как
Name=JohnиAge=0.затем я сделал значение возраста в Javascript строкой... то есть
var person = { Name: "john", Age: "9" }и это просто замечательно...
Это потому, что MVC-связующие вроде сосут. Тем не менее, они работают довольно хорошо, если все значения JSON приходят в виде строки.
в JS, если вы сделаете это
var myObject = {thisNumber:1.6}; myObject.thisNumber=myObject.thisNumber-.6;он будет оценивать до 1, а не до 1,0
поэтому, когда вы отправили его на сервер, он попытается привязать к поплавку этого имени, и он не найдет его, так как он перешел на 1 вместо 1.0. Его очень хромой и сумасшедший, что инженеры MS не придумали решение по умолчанию для этого. Я нахожу, если вы строите все привязки достаточно умны, чтобы найти вещи.
поэтому перед отправкой данных запустите его, Хотя строковый оператор, который также преобразует все значения в строки.
все предыдущие ответы были велики, чтобы указать мне на решение подобной проблемы. Я должен был опубликовать
x-www-form-urlencodingвместоapplication/json(опция по умолчанию, если параметр contentType отсутствует), чтобы иметь возможность передать__RequestVerificationTokenи одновременно столкнулся с проблемой, когда свойства объекта в массиве не связывают свои ценности. Способ решить эту проблему-понять внутреннюю работу MVC model binder.Итак, в основном, когда вам нужно предоставить маркер проверки, вы ограничены с атрибутом проверки. И вы должны предоставить токен в качестве параметра, а не как часть JSON-объекта, который вы отправляете. Если вы не будете использовать
ValidateAntiForgeryToken, вы могли бы поладить с JSON.преобразовать в строки. Но если бы вы захотели, то не смогли бы передать жетон.я нюхал трафик на бэкэнд, когда
ContentTypeбылx-www-form-urlencodingи я заметил, что мой массив сложных объектов был сериализован в что-то вроде этого:klo[0][Count]=233&klo[0][Blobs]=94. Этот массив изначально был частью корневого объекта, скажем, некоторой модели. Это выглядело вот так:model.klo = [{ Count: 233, Blobs: 94}, ...].на задней стороне это
kloсвойство создавалось MVC binder с тем же количеством элементов, которое я отправил. Но сами эти элементы не получили значений для своих свойств.решение
чтобы справиться с этим я исключил
kloсвойство от объекта модели на стороне клиента. В Я написал этот код:data: $.param(model) + "&" + arrayOfObjectsToFormEncoding("klo", [{ Count: 233, Blobs: 94}, ...]) .... function arrayOfObjectsToFormEncoding (modelPropertyName, arrayOfObjects) { var result = ""; if (arrayOfObjects && typeof arrayOfObjects == "object") { for (var i = 0; i < arrayOfObjects.length; i++) { var obj = arrayOfObjects[i]; if (obj) { for (var p in obj) { if (obj.hasOwnProperty(p)) { result += encodeURIComponent(modelPropertyName + "[" + i + "]." + p) + "=" + encodeURIComponent(obj[p]) + "&"; } } } } } if (result[result.length - 1] == "&") { result = result.substr(0, result.length - 1); } return result; }функция преобразует массив сложного объекта в форму, которая распознается MVC-связующим. Форма-это
klo[0].Count=233&klo[0].Blobs=94.
Comments