skip to Main Content

I have a dynamic json string:

[{
  "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",
}]

is it a good idea to search in json object for string that contains , an idea

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

How I can parse the string to Decimal and keep the decimal separator?

2

Answers


  1. Change the decimal separator to ,, You can rewrite the convert method as follows:

    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);//#,#
    }
    

    add reference to Json.NET

    APPROACH 1: The Easy way

    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);//#,#
        }
    }
    

    usage:

    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);
    

    APPROACH 2: The Ideal way

    Roll your own custom 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?);
        }
    }
    

    usage:

    string json = File.ReadAllText("json1.json");
    var obj = JsonConvert.DeserializeObject<List<Converted>>(json,new NiceDecimalConverter());
    Console.WriteLine(obj.Count);
    
    Login or Signup to reply.
  2. you can try this code

        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;
    }
    

    Since nobody knows what value fc is – is it one number, or two you can change ConvertToDecimal accordingly.

    Or you can deserialize it using c# class

    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; }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search