Arhn - архитектура программирования

Как десериализовать строку в JObject без экспоненциальной записи в С#

У меня есть такая строка:

var str = "{'data': {'someProperty': 0.00001}}";

Когда я разбираю его в JObject вот так

var jObject = JObject.Parse(str);

Мой jObject выглядит так:

{"data": {"someProperty": 1E-05}}

Мне нужно избавиться от научной нотации, чтобы полученный JObject выглядел как оригинальный json.

Мне удалось сделать это, используя более позднюю версию Newtonsoft.Json:

var serializer = new JsonSerializer { FloatParseHandling = FloatParseHandling.Decimal };
using (System.IO.TextReader tr = new System.IO.StringReader(str)
using (var jsonReader = new JsonTextReader(tr))
{
    var jp = serializer.Deserialize(jsonReader);
    var jObject = JObject.FromObject(jp);
}

Но мне нужно добиться того же результата, используя Newtonsoft.Json версии 3.5, в которой нет свойства FloatParseHandling. Я предполагаю, что мне нужно каким-то образом реализовать JsonConverter, но я понятия не имею, как это сделать, поскольку мой реальный json намного сложнее, чем тот, что в примере, и мне нужно правильно обрабатывать все значения с плавающей запятой.

Итак, каким будет правильный способ получить JObject без экспоненциальной записи для значений с плавающей запятой с использованием Newtonsoft 3.5?


  • Оболочка строк и свойств с разбором. 06.12.2019
  • Возможный дубликат: stackoverflow.com /вопросы/1546113/ 06.12.2019
  • вы можете преобразовать значение в десятичное, которое вернет правильное значение, и использовать ToString(), если вам нужно работать со строковыми значениями. пример var someProperty = ((decimal) jObject["data"]["someProperty"]).ToString(); 06.12.2019

Ответы:


1

Следующее производит объект, который вы ищете

JObject.Load(new JsonTextReader(new StringReader(str)) { FloatParseHandling = FloatParseHandling.Decimal }, null)

взято из здесь:

РЕДАКТИРОВАТЬ: JTokenTypes в NewtonSoft v 3.5.8 ограничены числами с плавающей запятой и целым числом (в отношении десятичного числа). В этой версии нет десятичного типа, и поэтому невозможно иметь десятичное значение в этом JObject.

JTokenTypes из v3 от newtonsoft

    None = 0,
    Object = 1,
    Array = 2,
    Constructor = 3,
    Property = 4,
    Comment = 5,
    Integer = 6,
    Float = 7,
    String = 8,
    Boolean = 9,
    Null = 10,
    Undefined = 11,
    Date = 12,
    Raw = 13,
    Bytes = 14

Правильный способ сделать это — обновить пакет Newtonsoft :)

06.12.2019
  • Спасибо. Но я указал, что не могу использовать FloatParseHandling. 06.12.2019
  • Это хорошо для десериализации json, которые имеют только свойство типа float или строковое представление числа с плавающей запятой. Мой json сложен с вложенными объектами, свойствами разных типов и массивами. Мне нужно, чтобы он был десериализован так же, как JObject.Parse(), но только числа должны быть десериализованы без научной нотации 06.12.2019
  • @ИльяИваницкий, посмотри мой РЕДАКТИРОВАТЬ. 06.12.2019
  • Сейчас самое время официально предложить вашему руководству обновить версии. Должно быть довольно легко показать, что для бизнеса было бы более целесообразно обновлять номера версий, чем заставлять одного из их разработчиков тратить часы или даже дни на то, что инструмент, который они уже используют, может сделать с полки, если бы они только не отставали от него. обновления. 06.12.2019
  • @ИльяИваницкий отвечает на твой вопрос 13.12.2019
  • Ну, я думаю, нет лучшего варианта, чем обновить версию. Так что я отмечу этот ответ. Спасибо всем. 17.12.2019

  • 2

    Предоставленный Джавадом код — не лучшее решение, потому что он приведет к утечке памяти. StringReader и JsonTextReader оба реализуют интерфейс IDisposable и поэтому должны быть удалены, если они больше не используются. Более безопасным кодом будет:

    public JObject CustomJObjectLoad(string str)
    {
        using (var stringReader = new StringReader(str))
        {
            using (var jsonReader = new JsonTextReader(stringReader) { FloatParseHandling = FloatParseHandling.Decimal })
            {
                return JObject.Load(jsonReader, null);
            }
        }
    }
    
    16.06.2020

    3

    Вы также можете создать простой объект POCO. и убедитесь, что someProperty имеет тип string, а затем десериализуйте строку json

    var myObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourObject>(json)
    
    06.12.2019
  • Примерно так же сказал и мой ответ :) 06.12.2019

  • 4

    Во-первых, ваш json недействителен :) Он должен иметь двойные кавычки:

    {"data": {"someProperty": 0.00001}}
    

    Но еще лучше, используя стандартную оболочку, было бы:

    {"Data": {"SomeProperty": 0.00001}}
    

    И тогда мы можем сделать это:

    var str = "{\"Data\": {\"SomeProperty\": 0.00001}}";
    dynamic myObject = JsonConvert.DeserializeObject(str);
    var val = myObject.Data.SomeProperty.ToString("0." + new string('#', 339));
    

    тогда val будет: "0.00001"

    (Примечание. Я украл решение из: Двойное преобразование в строку без научного обозначения)

    06.12.2019
  • Спасибо, но я хотел бы по возможности избегать создания классов, так как я не могу гарантировать точную форму json. 06.12.2019
  • У меня есть сложный json со многими свойствами, вложенными объектами, массивами и т. д. SomeProperty просто для примера. Мне нужно, чтобы все значения с плавающей точкой обрабатывались правильно. 06.12.2019
  • Хорошо, я прочитал правки к вашему ОП. Теперь я лучше понимаю, что вы пытаетесь сделать. Вы хотите изменить способ сериализации двойников. Но, могу я спросить, почему? Для любых математических целей научная запись по-прежнему будет работать нормально. Я предполагаю, что вы хотите изменить его только для отображения, верно? И если это так, почему бы просто не сделать преобразование прямо перед отображением? 06.12.2019
  • Использование не в моей компетенции. Мне нужно предоставить json для третьей стороны, и это их требование. 06.12.2019
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..