#c# #json #serialization #deserialization
#c# #json #сериализация #десериализация
Вопрос:
Я создаю дерево навигации и сохраняю структуру, используя эту функцию, в массиве
function parseTree(html) {
var nodes = [];
html.parent().children("div").each(function () {
var subtree = $(this).children("div");
var item = $(this).find(">span");
if (subtree.size() > 0)
nodes.push([item.attr("data-pId"), item.attr("data-id"), parseTree(subtree)]);
else
nodes.push(item.attr("data-pId"), item.attr("data-id"));
});
return nodes;
}
Затем я сериализую данные
var tree = $.toJSON(parseTree($("#MyTree").children("div")));
Получаем этот массив
[
["881150024","881150024",
[
"994441819","881150024",
"214494418","881150024"
]
],
["-256163399","-256163399",
[
"977082012","-256163399",
"-492694206","-256163399",
[
"1706814966","-256163399",
["-26481618","-256163399"]
]
]
]
]
И отправить его с помощью ajax
$.ajax({
url: "Editor/SerializeTree",
type: "POST",
data: { tree: tree },
success: function (result) {
alert("OK");
}
});
Вопрос: Как мне десериализовать этот JSON с помощью JavaScriptSerializer в C #?
Ответ №1:
Здесь кажется, что у вас есть массив узлов, и у каждого узла есть набор строк или другой массив узлов, верно? Первое, что вы могли бы сделать, это просто десериализовать это в List<object>
вот так:
string treeData = "..."; // The JSON data from the POST
JavaScriptSerializer js = new JavaScriptSerializer();
List<object> tree = js.Deserialize <List<object>>(treeData);
Это превратит ваш JSON в список объектов, хотя вам нужно будет вручную выяснить, что есть что (если каждый объект представляет собой строку или другой List<object>
).
Однако, как правило, это помогает иметь какой-то класс или структуру для представления «схемы» для данных, которые вы предоставляете сериализатору, но это требует немного больше работы, чем указано выше.
В этом случае вам понадобятся, чтобы ваши входные данные были реальным объектом JSON, а не просто массивом. Допустим, у вас есть этот JSON (на основе приведенных выше данных):
{id: "root", children: [
{id: "881150024"},
{id: "881150024", children: [
{id: "994441819"}, {id: "881150024"}]},
{id: "-256163399"},
{id: "-256163399", children: [
{id: "-492694206"},
{id: "-256163399", children: [
{id: "1706814966"},
{id: "-256163399", children: [
{id: "-26481618"}, {id: "-256163399"}]}
]}]}]}
Если у вас есть класс, подобный этому:
public class Node
{
public String id;
public List<Node> children;
}
Затем вы можете сделать что-то вроде:
string treeData = "..."; // The JSON data from the POST
JavaScriptSerializer js = new JavaScriptSerializer();
Node root = js.Deserialize<Node>(treeData);
С этим будет намного проще работать в коде.
Комментарии:
1. Хорошо описано! Я использовал второе решение. Мне просто нужно было исправить эту строку List<Узел> root = js.Десериализовать<Список<Узел>>(дерево); Большое спасибо. Это был мой первый скрипт с десериализацией 🙂
Ответ №2:
Принимая во внимание ответ @_rusty.
В MVC3 можно преобразовать данные JSON в действия, поэтому ваш код контроллера был бы очень простым
[HttpPost]
public void SerializeTree(IList<Node> tree)
{
// tree is deserialized JSON here
}
Комментарии:
1. Спасибо, Александр! Я использую MVC2 прямо сейчас. Когда я обновлю его до 3-й версии, я попробую это прекрасное решение. 🙂
2. @podeig, я бы не стал ждать 🙂 и использовал MvcFutures для получения требуемого решения. Это очень просто и красиво, проверьте это haacked.com/archive/2010/04/15 /…
Ответ №3:
Для тех немногих из нас, кто все еще использует VB.Сеть здесь и там:
Imports System.Web.Script.Serialization
'wsvcResponse<string> contains the following JSON object: { "foo":"bar", "foo2": { "bar2": "foobar" } }
Dim jsSerializer As New JavaScriptSerializer()
Dim jsonObject As List(Of Object) = jsSerializer.Deserialize(Of Object)(wsvcResponse)
Dim foo As String = jsonObject("foo").ToString ' "bar"
Dim bar2 As String = jsonObject("foo2")("bar2").ToString ' "foobar"
Комментарии:
1. Действительно вопрос новичка — в
Dim jsonObject As List(Of Object)
, мне заменитьObject
класс, который я создал, или просто оставить его какObject
?2. Я использую универсальный класс Object (что для меня редкость, поскольку я обычно использую явные типы) главным образом потому, что я не смог найти лучшего способа получить результаты приведения метода Deserialize(). Моим первоначальным побуждением было: «.Десериализовать(из списка (из строки))(wsvcResposne), но я не смог заставить это работать так, как ожидалось.