Как упорядочить / нормализовать json в C #, например, JSON.stringify()

#c# #.net-core #.net-core-3.0

#c# #.net-core #.net-core-3.0

Вопрос:

Интересно, есть ли лучший, менее случайный способ делать со строками JSON то, что JSON.Stringify делает что-то еще?

 string json = "{test: 'test'}";
var stringified = JsonConvert.SerializeObject(JsonConvert.DeserializeObject<dynamic>(json));
Console.WriteLine(stringified); //Prints {"test":"test"}
  

Похоже, что в C # нет способа нормализовать представление строки в противном случае. Я не уверен в новом .NET Core 3.0 и его новых библиотеках JSON.

JSON.stringify Итак, мне было интересно, есть ли лучший способ выполнения обработки, как тот, который я отметил. Еще лучше, если он уже встроен в фреймворк.

Игровая площадка может быть в MDN Web Docs .

Есть один пример на https://github.com/ethereum/wiki/wiki/JavaScript-API#web3tohex там, где он появляется, даже один и тот же {test: 'test'} объект JSON сначала строится в строку, а затем кодируется в шестнадцатеричном формате. В C # тоже могут быть случаи, когда кто-то читает строки из других источников, и вывод должен быть в строковой форме независимо от этого.

Комментарии:

1. Что вы подразумеваете под » нормализовать «? По какой причине вы десериализуете строку json, а затем немедленно сериализуете ее до того, как она началась? Это просто цитирование?

2. Не лучше ли было бы создать конкретную структуру классов и сериализовать ее?

3. @Crowcoder В примере, который у меня есть, есть объект Javascript, который я хотел бы иметь в виде строки JSON для последующей обработки. Эта последующая обработка может закодировать его каким-либо другим методом, и результат не будет одинаковым с помощью и без stringifying . Генерала в данном случае нет. Цель состоит в том, чтобы принять JSON и сделать так, как JSON.stringify, как можно точнее.

4. Является ли ваш пример даже допустимым json?

5. @maccetura Это так. Сначала это объект JS, затем он преобразуется в JSON.

Ответ №1:

Проблема в том, что вы сравниваете наличие ОБЪЕКТА в JS, затем преобразуете его в JSON, с наличием СТРОКИ в C #, а затем преобразуете ее в JSON.

Если бы у вас был объект C #, эквивалент был JSON.stringify() бы просто JsonConvert.SerializeObject(myObject) . C # не принимает синтаксис JSON (как это делает JS) для определения объекта.

В опубликованных вами примерах MDN вы видите:

 console.log(JSON.stringify({ x: 5, y: 6 }));
  

Эквивалент c # будет (запустите его):

  Console.WriteLine(JsonConvert.SerializeObject(new { x = 5, y = 6 });
  

Но именно так работает синтаксис C # (Javascript позволяет JSON определять объекты без необходимости их разбора… C # имеет другой синтаксис для определения встроенных объектов — анонимных или нет -).

Эквивалент в Javascript для примера, который вы опубликовали (имеющий строку, а не объект), будет:

 const jsString = '{"test": "test"}';
console.log(JSON.stringify(JSON.parse(jsString)));
  

Это немного отличается от простого использования JSON.stringify() и соответствует тому, что вы видите в C # (десериализация затем сериализация)

Обратите внимание также, что синтаксис, который Javascript позволяет определять объекты, не обязательно является «строго допустимым JSON»… приведенное выше с этой строкой завершится неудачей:

 const jsString = '{ test: "test" }';
  

Принимая во внимание, что этот способ определения объекта был бы допустимым:

 const jsObject = { test: "test" };
  

(это, по сути, причина, по которой вы можете захотеть «нормализовать» его, как вы его называете)


Все, что сказано

если десериализация / сериализация является проблемой, как в «looks», просто создайте метод расширения … что-то вроде:

 public static string NormalizeJson(this string input) {
   return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<object>(input));
}
  

И тогда вы можете просто сделать это для любой строки (если вы добавили using сверху):

 myJsonInput.NormalizeJson();
  

Посмотрите на это в действии

Комментарии:

1. Да. Возможно, мне следовало подчеркнуть, что входные данные для кода C # представляют собой простые строки, считываемые из некоторого источника, и могут быть как в объектной нотации JSON, так и в строковой форме (с потенциальными крайними случаями), и до сих пор выполнение этого танца с динамическим объектом, по-видимому, дает результат stringified JSON и, возможно, изящно охватывает крайние случаи, как тот, который вы упомянули. То есть я не ищу то, что эквивалентно в коде, но достаточно близко в результате, вывод. И если есть менее хакерский способ сделать это, а не этот танец. Похоже, это не так.

2. @Veksi Я добавил дополнительный комментарий, показывающий, как преобразовать его в метод расширения, если вы хотите, чтобы он был «чище»

3. ХОРОШО. 🙂 Я думаю, что это самое близкое, что можно получить, кроме именования метода как Stringify , но я не знаю, будет ли это правильным вызовом. Я думаю, что действительно нет существенно лучшего способа добиться этого, но, возможно, это была хорошая дискуссия, чтобы оживить умы.

4. Если вы хотите вызвать его Stringify , я бы не стал использовать это как метод расширения и создал статический класс с именем Json , используя статический метод Stringify … обратите внимание, однако, что еще раз: JSON.Stringify в Javascript НЕ нормализуются «строки json». Он сериализует объекты javascript. Это просто не то же самое, что вы делаете здесь

Ответ №2:

я думаю, вы пропустили форматирование, это может быть

 public static string NormalizeJson(this string value)
{
  return JsonConvert.SerializeObject(JsonConvert.DeserializeObject<object>(value), Newtonsoft.Json.Formatting.Indented);
}