Как сериализовать ExpandoObject с помощью ServiceStack JsonSerializer? - PullRequest
6 голосов
/ 22 августа 2011

Можно ли заставить ServiceStack JsonSerializer сериализовать ExpandoObject как плоский объект, а не как словарь?Примерно что-то примерно такое:

{"x":"xvalue","y":"\/Date(1313966045485)\/"}

Я пытаюсь сравнить сериализацию JSON ExpandoObject с использованием трех разных систем: .NET BCL JavaScriptSerializer, Newtonsoft JSON.NET и предложения ServiceStack JSON.

Я начинаю с довольно простого динамического объекта.

dynamic test = new ExpandoObject();
test.x = "xvalue";
test.y = DateTime.Now;

Сериализатору кажется проще обрабатывать ExpandoObject как IDictionary<string, object>.И BCL, и ServiceStack начинаются таким образом, хотя и идут совершенно разными путями с результатом.

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
Console.WriteLine(javaScriptSerializer.Serialize(test));
// [{"Key":"x","Value":"xvalue"},{"Key":"y","Value":"\/Date(1313966045485)\/"}]

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(test));
// ["[x, xvalue]","[y, 8/21/2011 16:59:34 PM]"]

Я бы предпочел, чтобы ExpandoObject сериализовался больше, так как он собран в коде, как типичный класс будет сериализован.Вы можете добавить переопределенный сериализатор JavaScript в систему BCL для IDictionary<string, object>.Это прекрасно работает, если предположить, что на самом деле у человека нет IDictionary<string, object>, который должен оставаться таким (чего у меня пока нет).

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJsonConverter() });
Console.WriteLine(javaScriptSerializer.Serialize(test));
// {"x":"xvalue","y":"\/Date(1313966045485)\/"}

К сожалению, мне все еще нужен способ получить JsonSerializer из ServiceStack.обрабатывать ExpandoObject таким же образом.Как я могу подключиться к системе ServiceStack, чтобы сделать это возможным?

Обновление: Хотя это не вариант для моих целей, похоже, ServiceStack прекрасно обрабатывает анонимные объекты.

Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(new { x = "xvalue", y = DateTime.Now }));
// {"x":"xvalue","y":"\/Date(1313980029620+0000)\/"}

1 Ответ

1 голос
/ 22 августа 2011

В JsonSerializer ServiceStack нет доступных хуков, к которым вы можете подключиться, чтобы изменить это поведение, но я буду более чем рад получить запрос на получение, который это делает;)

Классы, которые вы будете использоватьнеобходимо изменить:

  • JsWriter.cs (строка 223) - вставить код для обнаружения объекта раскрытия и вернуть делегат, который записывает объект развертывания так, как вы этого хотите.
  • JsReader (строка 42) - вставьте код, чтобы обнаружить объект экспандо, и верните делегат, чтобы прочитать содержимое строки и десериализовать его обратно в эксплоо

Я полагаю, что код для работы с объектом раскрытия похож на словарь, поэтому вы должны иметь возможность использовать классы реализации словаря для руководства (т. Е. WriteDictionary.cs и DeserializeDictionary.cs )

Не стесняйтесь использовать форум ServiceStack, если у вас есть какие-либо вопросы / проблемы по этому вопросу: https://groups.google.com/forum/#!forum/servicestack

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...