Как сериализовать ExpandoObject с помощью ServiceStack JsonSerializer?
Можно ли заставить ServiceStack JsonSerializer сериализовать ExpandoObject как плоский объект, а не словарь? Что-то примерно приближенное к этому:
{"x":"xvalue","y":"/Date(1313966045485)/"}
Я пытаюсь сравнить сериализацию JSON ExpandoObject
с использованием трех различных систем: .NET BCL JavaScriptSerializer, Newtonsoft JSON.NET, и предложение Servicestack's 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, чтобы сделать это возможным?
Update: хотя это не вариант для моего использования, похоже, что ServiceStack отлично обрабатывает анонимные объекты.
Console.WriteLine(ServiceStack.Text.JsonSerializer.SerializeToString(new { x = "xvalue", y = DateTime.Now }));
// {"x":"xvalue","y":"/Date(1313980029620+0000)/"}
1 ответ:
В Jsonserializer ServiceStack нет никаких крючков, которые вы можете подключить, чтобы изменить это поведение, но я буду более чем счастлив принять запрос на вытягивание, который это делает;)
Классы, которые вам нужно будет изменить:
- JsWriter.cs (строка 223) - вставка кода для обнаружения объекта expando и возврата делегата, который записывает объект expando так, как вы хотите.
- JsReader (строка 42) - вставить код для обнаружения объекта expando и возврата делегат для чтения содержимого строки и десериализации его обратно в expando
Я полагаю, что код для работы с объектом expando похож на словарь, поэтому вы должны иметь возможность использовать классы реализации словаря, чтобы направлять вас (т. е. WriteDictionary.cs и DeserializeDictionary.cs )
Не стесняйтесь использовать форум ServiceStack, если у вас есть еще какие-либо вопросы / проблемы по этому поводу: https://groups.google.com/forum/#! forum / servicestack