Преобразовать строку в десятичную в Dynimc json

У меня есть динамическая строка json:

[{
  "Id": "1",
  "Description": "Scenario 1",
  "fc": "-45156,60000",
  "fci": "-45156,60000",
  "fcii": null,
  "fciii": null,
  "fciv": null,
},
{
  "Id": "1",
  "Description": "Scenario 2",
  "fc": "-45156,60000",
  "fci": "-45156,60000",
},
{
  "Id": "1",
  "Description": "Scenario 3",
  "fc": "-45156,60000",
  "fci": "-45156,60000",
  "fcii": null,
},
{
  "Id": "1",
  "Description": "Scenario 4",
  "fc": "-45156,60000",
}]

Стоит ли искать в объекте json строку, содержащую , идею

    public decimal ConvertToDecimal(string s)         
    {             
        if (s.Contains(','))             
        {                 
            return decimal.Parse(s.Replace(',', '.'));             
        }             
        else                  
            return SomeDecimalValue;         
     }

Как я могу разобрать строку на десятичную и сохранить десятичный разделитель?

Нет, это хорошая идея. Хорошая идея - использовать десятичный разбор попытки. десятичный вывод; decimal.TryParse("123", выход);

Muhammad Bashir 22.02.2023 11:02

Я могу сказать вам sudo, если("123".contains(',')) разделить и попытаться проанализировать каждый из них, иначе попробуйте проанализировать результат

Muhammad Bashir 22.02.2023 11:04

Это очень, очень плохая идея. JSON имеет отдельные обозначения для строк и десятичных знаков. "-45156,60000" не является десятичной дробью. -45156, 60000 и -45156.6 — десятичные дроби. Если вы хотите сериализовать координаты или пары значений, используйте правильную нотацию JSON — либо объект, либо массив.

Panagiotis Kanavos 22.02.2023 11:05

Что означает «сохранять десятичный разделитель»? Вы знаете, что тип decimal вообще не имеет разделителя, и только строковое представление, основанное на текущей культуре, будет отображать разделитель? например. dotnetfiddle.net/lWBd6D

Rand Random 22.02.2023 11:07

@MuhammadBashir, и тогда вам придется иметь дело с неправильными интерпретациями десятичных и тысячных разделителей. В JSON уже есть допустимые способы указания чисел и значений, поэтому людям не нужно разбивать и анализировать

Panagiotis Kanavos 22.02.2023 11:08

Что должны содержать fc и fci? Одно значение или два? Если это десятичное число, то почему это строка, а не число? Реальное решение здесь — использовать хороший формат JSON, а не пытаться восстановиться из плохого и неоднозначного формата.

Panagiotis Kanavos 22.02.2023 11:09

Кроме того, этот ConvertToDecimal уже сломан. В разных культурах используются разные форматы, и использование неправильного приведет к неверным значениям. Кто сказал, что , здесь десятичный разделитель? Проблема не может быть устранена путем произвольной замены разделителей. Если вы хотите анализировать числа с использованием определенной локали, все равно передайте ее Parse как CultureInfo, например decimal.Parse(str,CultureInfo.GetCultureInfo("fr-FR")). Однако вы должны знать, что такое правильный язык. В противном случае вы получите -4515660000

Panagiotis Kanavos 22.02.2023 11:14

Если вы замените , на . и ваш код будет работать за пределами Китая и стран Тихоокеанского региона, decimal.Parse создаст -4515660000. Если бы не Китай, можно было бы сказать, что в большинстве стран мира то, что вы сделали, привело бы к неправильному результату.

Panagiotis Kanavos 22.02.2023 11:16

Это вывод json, я не могу его изменить

MedAmin 22.02.2023 11:27
Конечные и Readonly классы в PHP
Конечные и Readonly классы в PHP
В прошлом, когда вы не хотели, чтобы другие классы расширяли определенный класс, вы могли пометить его как final.
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
От React к React Native: Руководство для начинающих по разработке мобильных приложений с использованием React
Если вы уже умеете работать с React, создание мобильных приложений для iOS и Android - это новое приключение, в котором вы сможете применить свои...
БЭМ: Конвенция об именовании CSS
БЭМ: Конвенция об именовании CSS
Я часто вижу беспорядочный код CSS, особенно если проект большой. Кроме того, я совершал эту ошибку в профессиональных или личных проектах и...
Революционная веб-разработка ServiceNow
Революционная веб-разработка ServiceNow
В быстро развивающемся мире веб-разработки ServiceNow для достижения успеха крайне важно оставаться на вершине последних тенденций и технологий. По...
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Как добавить SEO(Search Engine Optimization) в наше веб-приложение и как это работает?
Заголовок веб-страницы играет наиболее важную роль в SEO, он помогает поисковой системе понять, о чем ваш сайт.
Конфигурация Jest в angular
Конфигурация Jest в angular
В этой статье я рассказываю обо всех необходимых шагах, которые нужно выполнить при настройке jest в angular.
1
9
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Измените десятичный разделитель на ,. Вы можете переписать метод преобразования следующим образом:

public decimal? ConvertToDecimal(string s)
{
    System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-US");
    culture.NumberFormat.NumberDecimalSeparator = ",";
    if (string.IsNullOrWhiteSpace(s))
        return null;
    return Decimal.Parse(s, culture);//#,#
}

Добавить ссылку на Json.NET

ПОДХОД 1: Простой способ

public class Converted
{
    public string Id { get; set; }
    public string Description { get; set; }
    public decimal? fc { get; set; }
    public decimal? fci { get; set; }
    public decimal? fcii { get; set; }
    public decimal? fciii { get; set; }
    public decimal? fciv { get; set; }
}

//from: https://json2csharp.com/
public class Root
{
    public string Id { get; set; }
    public string Description { get; set; }
    public string fc { get; set; }
    public string fci { get; set; }
    public string fcii { get; set; }
    public string fciii { get; set; }
    public string fciv { get; set; }

    //https://stackoverflow.com/questions/3013442/convert-string-to-decimal-retaining-the-exact-input-format
    public Converted Convert() {
        return new Converted()
        {
            Id = Id,
            Description = Description,
            fc = ConvertToDecimal(fc),
            fci = ConvertToDecimal(fci),
            fcii = ConvertToDecimal(fcii),
            fciii = ConvertToDecimal(fciii),
            fciv = ConvertToDecimal(fciv)
        };
    }

    public decimal? ConvertToDecimal(string s)
    {
        System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-US");
        culture.NumberFormat.NumberDecimalSeparator = ",";
        if (string.IsNullOrWhiteSpace(s))
            return null;
        return Decimal.Parse(s, culture);//#,#
    }
}

Применение:

using Newtonsoft.Json;
using System.Globalization;

string json = File.ReadAllText("json1.json");
var obj = JsonConvert.DeserializeObject<List<Root>>(json);
List<Converted> ideal = new List<Converted>();
obj.ForEach(x =>
{
   ideal.Add(x.Convert());
});
Console.WriteLine(ideal.Count);

ПОДХОД 2: Идеальный способ

Сверните свой собственный JsonConverter

public class Converted
{
    public string Id { get; set; }
    public string Description { get; set; }

    [JsonConverter(typeof(NiceDecimalConverter))]
    public decimal? fc { get; set; }

    [JsonConverter(typeof(NiceDecimalConverter))]
    public decimal? fci { get; set; }

    [JsonConverter(typeof(NiceDecimalConverter))]
    public decimal? fcii { get; set; }

    [JsonConverter(typeof(NiceDecimalConverter))]
    public decimal? fciii { get; set; }

    [JsonConverter(typeof(NiceDecimalConverter))]
    public decimal? fciv { get; set; }
}

//from: https://stackoverflow.com/a/30083923/223752
public class NiceDecimalConverter : JsonConverter
{
    public decimal? ConvertToDecimal(object o)
    {
        string s = Convert.ToString(o);
        System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-US");
        culture.NumberFormat.NumberDecimalSeparator = ",";
        if (string.IsNullOrWhiteSpace(s))
            return null;
        return Decimal.Parse(s, culture);//#,#
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var d = (decimal?)value;
        if (!d.HasValue)
        {
            writer.WriteValue("null");
        }
        else
        {
            var niceLookingDecimal = d.ToString().Replace(".", ",");
            writer.WriteValue(niceLookingDecimal);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return ConvertToDecimal(reader.Value);
    }

    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(decimal?);
    }
}

Применение:

string json = File.ReadAllText("json1.json");
var obj = JsonConvert.DeserializeObject<List<Converted>>(json,new NiceDecimalConverter());
Console.WriteLine(obj.Count);
Ответ принят как подходящий

Вы можете попробовать этот код

    var jArr = JArray.Parse(json);

    foreach (var item in jArr)
    {
        foreach (var prop in ((JObject)item).Properties())
        {
if (prop.Name= = "Id" || prop.Name= = "Description") continue; //you can remove it
            var val = ConvertToDecimal((string)prop.Value);
            if (val != null) prop.Value = val;
        }
    }

      json = jArr.ToString();

public decimal? ConvertToDecimal(string s)
{
    if (!string.IsNullOrEmpty(s))
        if (decimal.TryParse(s.Replace(',', '.'), out var val))
            return val;
    return null;
}

Поскольку никто не знает, что такое значение fc - это одно число или два, вы можете соответствующим образом изменить ConvertToDecimal.

Или вы можете десериализовать его, используя класс С#

List<Forecast> forecast= jArr.ToObject<List<Forecast>>();

public class Forecast
{
    public int Id { get; set; }
    public string Description { get; set; }

    [JsonExtensionData]
    public Dictionary<string, object> Extra { get; set; }
}

Другие вопросы по теме