Оптимальный код парсинга string в decimal

127
18 июня 2019, 13:00

Имею некий джейсон который десериализую в объект, одно из полей которого нужно спарсить в decimal

using System;
using Newtonsoft.Json;
using static System.Convert;
using static System.Globalization.CultureInfo;
using static System.Globalization.NumberStyles;
public class OpenOrder
{
   ...
   [JsonProperty("margin")]   
   public decimal margin;
}

но периодически пиходят данные в форматах (123,345 или 1.09E+30) то с точками, то с запятыми, то в экспоненциальном...

нашел вариант, но как-то он мне не по душе.

[JsonProperty("margin")]
private string Margin
{ 
  set { decimal.TryParse(value, Any, InvariantCulture, out margin); } 
}
public decimal margin;

Может кто-то сталкивался с подобным? И подскажет какую-то упрощенную конструкцию?

Answer 1

Это известная проблема с разбором decimal из экспоненциальной формы, был даже push с фиксом, но похоже его пока не включили в версию.

Можно воспользоваться атрибутом JsonConstructor, тогда не надо будет заводить отдельное поле:

public class OpenOrder {
    ...
    public decimal margin;
    [JsonConstructor]
    public OpenOrder(string margin) {
        decimal.TryParse(margin, Any, InvariantCulture, out this.margin);
    }
    ...
}

на основе ответа @WarisSarwar

Либо использовать JsonConverter:

public class OpenOrder
{
    ...
    [JsonConverter(typeof(JsonExponentialConverter))]
    public decimal Margin { get; set; }
    ...
}

где JsonExponentialConverter может выглядеть так:

public class JsonExponentialConverter : JsonConverter
{
    public override bool CanRead { get { return true; } }
    public override bool CanConvert(Type objectType)
    {
        return true;
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        decimal d = 0;
        if (decimal.TryParse(reader.Value.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out d))
        {
            return d;
        }
        return d;
    }
}

перевод ответа @er-shoaib

READ ALSO
Изменение круговой диаграммы в OxyPlot

Изменение круговой диаграммы в OxyPlot

Свойство Value у PieSlice доступно только для чтенияПолучается, что для обновления диаграммы нужно каждый раз удалять сегмент из PieSeries

103
Ожидание нажатия кнопки в цикле

Ожидание нажатия кнопки в цикле

Подскажите пожалуйста! Пишу мини програму тестирования, прописал создание интерфейса метод вызывается из main

130
C# Как сохранить изменения в DataGridView?

C# Как сохранить изменения в DataGridView?

Сейчас у меня есть DataGridView, в котором отображается 1 из связанных таблицmdb Есть фрагмент кода:

186