-1

Given the following json document, what would be the best way to convert it to a valid object using a Converter? The trick comes in that the source json has the value property as string where it should be serialized as a float?

  {
    "metric": "metric",
    "operator": "GREATER_THAN",
    "value": "1",
    "status": "OK",
    "errorThreshold": "1"
  }

The resulting c# object:

public class Condition
{
    [JsonPropertyName("errorThreshold")]
    public string ErrorThreshold { get; set; }
    
    [JsonPropertyName("metric")]
    public string Metric { get; set; }
    
    [JsonPropertyName("operator")]
    public string Operator { get; set; }
    
    [JsonPropertyName("status")]
    public string Status { get; set; }
    
    [JsonPropertyName("value")]
    public double? Value { get; set; }
}

I'm toying here with a converter that makes use of reflection to do this, but this seems like using a shotgun to kill a earthworm.

Are there any more commonly established/recommended ways in doing this?

mieliespoor
  • 945
  • 2
  • 8
  • 23
  • If the JSON comes from a REST API, one reason a decimal may be represented as a string is that the most popular tool for generating clients, NSwag, tends to treat them as `float`, as you say you want. But using `float` instead of `decimal` is a Bad Idea™ if the value needs to be precise, so the API designer might have intentionally made it a string. – Kevin Krumwiede Mar 10 '22 at 23:34
  • The trick is very simple, forget System.Text.Json and use Newtonsoft.Json. You will have all kind of problem all the time if you continute to use system.text.json. – Serge Mar 10 '22 at 23:35
  • 1
    A converter is the established way to do it. See [this](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to?pivots=dotnet-6-0#registration-sample---jsonconverter-on-a-property), except make one for whatever data type you want. You don't need to switch to Newtonsoft – Crowcoder Mar 10 '22 at 23:37
  • @mieliespoor You will need a custom converter for allmost all your jsons. – Serge Mar 11 '22 at 00:13
  • What framework version are you using? .NET 5 or 6 or something else? If .NET 5 or later you can just use [`JsonNumberHandling.AllowReadingFromString`](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonnumberhandling?view=net-5.0). See [System.Text.Json: Deserialize JSON with automatic casting](https://stackoverflow.com/a/59099589/3744182). – dbc Mar 11 '22 at 00:15
  • And also [System.Text.Json deserialize uint](https://stackoverflow.com/a/67223318/3744182) for a solution using options. – dbc Mar 11 '22 at 00:21
  • @Crowcoder - a converter is not needed for this as of .NET 5. See [Allow or write numbers in quotes](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-invalid-json#allow-or-write-numbers-in-quotes). – dbc Mar 11 '22 at 00:22
  • @mieliespoor - do those two questions answer your sufficiently? – dbc Mar 11 '22 at 00:23
  • @dbc I decided to close this question as duplicate since you have answered a lot of very similar questions. – Serge Mar 11 '22 at 00:42

2 Answers2

0

well one way is

public class Condition
{
    [JsonPropertyName("errorThreshold")]
    public string ErrorThreshold { get; set; }
    
    [JsonPropertyName("metric")]
    public string Metric { get; set; }
    
    [JsonPropertyName("operator")]
    public string Operator { get; set; }
    
    [JsonPropertyName("status")]
    public string Status { get; set; }
    
    [JsonPropertyName("value")]
    public string Value { get; set{
            Double.TryParse(value, out ValNumeric);
         }; }
    
    public double ValNumeric = 0;
}
pm100
  • 48,078
  • 23
  • 82
  • 145
0

I would never use Text.Json for something except "Hello World", but you can do it this way, you do not need any extra properties

var conditionParsed = JsonDocument.Parse(json);
var condition =conditionParsed.Deserialize<Condition>();

if (double.TryParse( conditionParsed.RootElement.GetProperty("value").GetString(),out  double  value))  
condition.Value=value;

and change value property attribute

[System.Text.Json.Serialization.JsonIgnore]
public double? Value { get; set; }

or you can like this too

[JsonPropertyName("value")]
public string _value { get; set; }
 
[System.Text.Json.Serialization.JsonIgnore]
public double? Value
{
 get { return double.TryParse(_value, out double val)? val:null; }
 set { _value = value != null ? value.ToString(): null; }
}
    

but in this case you will need an extra public propery

Serge
  • 40,935
  • 4
  • 18
  • 45