#.net #json #serialization #formatting #javascriptserializer
#.net #json #сериализация #форматирование #javascriptserializer
Вопрос:
Я использую JavaScriptSerializer для сериализации объектов в файле в формат JSON. Но результирующий файл не имеет читаемого форматирования. Как я могу разрешить форматирование для получения читаемого файла?
Ответ №1:
Вы могли бы использовать JSON.NET сериализатор, он поддерживает форматирование JSON
string body = JsonConvert.SerializeObject(message, Formatting.Indented);
Вы можете загрузить этот пакет через NuGet.
Комментарии:
1. Вы даже можете установить желаемые параметры форматирования JsonConvert.SerializeObject(сообщение, Newtonsoft.Json. Форматирование. С отступом, новые настройки JsonSerializerSettings { ContractResolver = new Newtonsoft.Json. Сериализация. CamelCasePropertyNamesContractResolver() });
Ответ №2:
Вот мое решение, которое не требует использования JSON.NET и это проще, чем код, на который ссылается Алекс Жевжик.
using System.Web.Script.Serialization;
// add a reference to System.Web.Extensions
public void WriteToFile(string path)
{
var serializer = new JavaScriptSerializer();
string json = serializer.Serialize(this);
string json_pretty = JSON_PrettyPrinter.Process(json);
File.WriteAllText(path, json_pretty );
}
а вот и средство форматирования
class JSON_PrettyPrinter
{
public static string Process(string inputText)
{
bool escaped = false;
bool inquotes = false;
int column = 0;
int indentation = 0;
Stack<int> indentations = new Stack<int>();
int TABBING = 8;
StringBuilder sb = new StringBuilder();
foreach (char x in inputText)
{
sb.Append(x);
column ;
if (escaped)
{
escaped = false;
}
else
{
if (x == '\')
{
escaped = true;
}
else if (x == '"')
{
inquotes = !inquotes;
}
else if ( !inquotes)
{
if (x == ',')
{
// if we see a comma, go to next line, and indent to the same depth
sb.Append("rn");
column = 0;
for (int i = 0; i < indentation; i )
{
sb.Append(" ");
column ;
}
} else if (x == '[' || x== '{') {
// if we open a bracket or brace, indent further (push on stack)
indentations.Push(indentation);
indentation = column;
}
else if (x == ']' || x == '}')
{
// if we close a bracket or brace, undo one level of indent (pop)
indentation = indentations.Pop();
}
else if (x == ':')
{
// if we see a colon, add spaces until we get to the next
// tab stop, but without using tab characters!
while ((column % TABBING) != 0)
{
sb.Append(' ');
column ;
}
}
}
}
}
return sb.ToString();
}
}
Комментарии:
1. Зачем использовать
IDisposable
? Почему бы просто не создатьProcess
статический метод?2. @tenfour — вы абсолютно правы. Этот фрагмент кода взят из большего блока, который был упрощен для stackoverflow… Я еще больше упростлю это.
3. Это решение не для всех! У вас возникнут конфликты с изображением страницы (или форматом), если ваш проект является .NET 4 или если ваш проект не имеет веб-обозначения! Обратите внимание, что вы используете System.Web.Extensions (need .NET4.5!) для ввода System.Web.Script. Сериализация!! Для конкретного решения вам следует использовать NuGet для приобретения Newtonsoft и использовать JsonConvert.SerializeObject
4. Код был бы значительно проще и элегантнее, если бы вы использовали символы табуляции — кстати, именно для той цели, для которой они предназначены.
Ответ №3:
Я также хотел иметь возможность форматировать JSON, не полагаясь на сторонний компонент. Решение Марка Лакаты сработало хорошо (спасибо Марку), но я хотел, чтобы скобки и табуляция были такими же, как в ссылке Алекса Жевжика. Итак, вот измененная версия кода Марка, которая работает таким образом, на случай, если кто-то еще захочет этого:
/// <summary>
/// Adds indentation and line breaks to output of JavaScriptSerializer
/// </summary>
public static string FormatOutput(string jsonString)
{
var stringBuilder = new StringBuilder();
bool escaping = false;
bool inQuotes = false;
int indentation = 0;
foreach (char character in jsonString)
{
if (escaping)
{
escaping = false;
stringBuilder.Append(character);
}
else
{
if (character == '\')
{
escaping = true;
stringBuilder.Append(character);
}
else if (character == '"')
{
inQuotes = !inQuotes;
stringBuilder.Append(character);
}
else if (!inQuotes)
{
if (character == ',')
{
stringBuilder.Append(character);
stringBuilder.Append("rn");
stringBuilder.Append('t', indentation);
}
else if (character == '[' || character == '{')
{
stringBuilder.Append(character);
stringBuilder.Append("rn");
stringBuilder.Append('t', indentation);
}
else if (character == ']' || character == '}')
{
stringBuilder.Append("rn");
stringBuilder.Append('t', --indentation);
stringBuilder.Append(character);
}
else if (character == ':')
{
stringBuilder.Append(character);
stringBuilder.Append('t');
}
else if (!Char.IsWhiteSpace(character))
{
stringBuilder.Append(character);
}
}
else
{
stringBuilder.Append(character);
}
}
}
return stringBuilder.ToString();
}
Ответ №4:
Казалось, что нет встроенного инструмента для форматирования выходных данных JSON-сериализатора.
Я полагаю, причина, по которой это произошло, заключается в минимизации данных, которые мы отправляем по сети.
Вы уверены, что вам нужны форматированные данные в коде? Или вы хотите проанализировать JSON только во время отладки?
Существует множество онлайн-сервисов, которые предоставляют такую функциональность: 1, 2. Или автономное приложение: JSON Viewer.
Но если вам нужно форматирование внутри приложения, вы можете написать соответствующий код самостоятельно.
Комментарии:
1. В ссылке 2 говорится… Python 2.5 больше недоступен.