C
C#7mo ago
OkOk

JsonSerializer.Deserialize will not translate number to string

I am trying to deserialize JSON into an object and one of the JSON values is a is sometimes a string and sometimes a number which will not translate into a string property of an object. Previous forum questions recommend using the attribute JsonNumberHandling to translate possible numbers into strings but it doesn't seem to work in my simple example. My usage:
public class Extensions
{
[JsonNumberHandling(JsonNumberHandling.WriteAsString)]
public string position { get; set; }
}


HttpResponseMessage response = await client.GetAsync(urlTjänsteDomän);
PageResponse? page = JsonSerializer.Deserialize<PageResponse>(await response.Content.ReadAsStringAsync());
public class Extensions
{
[JsonNumberHandling(JsonNumberHandling.WriteAsString)]
public string position { get; set; }
}


HttpResponseMessage response = await client.GetAsync(urlTjänsteDomän);
PageResponse? page = JsonSerializer.Deserialize<PageResponse>(await response.Content.ReadAsStringAsync());
My error: System.InvalidOperationException: ''JsonNumberHandlingAttribute' is only valid on a number or a collection of numbers when applied to a property or field. See member 'position' on type 'Confluence.Domain.Info.Generator.Extensions'.'
12 Replies
OkOk
OkOk7mo ago
The JSON will sometimes look like this and sometimes it will have the 9 replaced by "None" { "results": [ { "extensions": { "position": 9 } } ] }
Angius
Angius7mo ago
Ah, malformed data, perfect lol I'd use a custom converter that converts it to an int? and returns null on "None" and a normal number otherwise
OkOk
OkOk7mo ago
@ZZZZZZZZZZZZZZZZZZZZZZZZZ The article I got this idea from says that this attribute is the way to do and it uses a converter already. So my question would be why it doesn't seem to work on my standard example when it does work for others. https://stackoverflow.com/questions/59097784/system-text-json-deserialize-json-with-automatic-casting
Stack Overflow
System.Text.Json: Deserialize JSON with automatic casting
Using .Net Core 3's new System.Text.Json JsonSerializer, how do you automatically cast types (e.g. int to string and string to int)? For example, this throws an exception because id in JSON is nume...
OkOk
OkOk7mo ago
@ZZZZZZZZZZZZZZZZZZZZZZZZZ It seems to me like it should be a normal task to deserialize JSON data which alternates between data types
Angius
Angius7mo ago
C# has no union types, there's no int|string so no, something being one of multiple types is not a normal task
OkOk
OkOk7mo ago
@ZZZZZZZZZZZZZZZZZZZZZZZZZ I mean it seems like a common problem calling an API which will give you JSON that might either answer with a number or a string like "N/A" To me it seems like something that would have a well known and documented C# solution
Angius
Angius7mo ago
It's only a problem when the data you get doesn't fit a strictly-typed schema So, yes, considering how garbage some of the APIs are, common enough That's why we have custom converters, for example A perfect fit for this case
OkOk
OkOk7mo ago
@ZZZZZZZZZZZZZZZZZZZZZZZZZ But JsonNumberHandlingAttribute is a custom converter And the JSON value is just the number 9, so why would it throw this error and why should I make yet another converter?
jcotton42
jcotton427mo ago
Some people shouldn't be allowed near computers
OkOk
OkOk7mo ago
@jcotton42 But it seems like a very real scenario where an api needs to sometimes show a number and sometimes a "N/A" "None" "NULL" "" etc
Angius
Angius7mo ago
You still wouldn't want to deserialize it to a string 7 is not a string And "None" should be treated as null Together, you get int?
PixxelKick
PixxelKick7mo ago
Just as an experiment what if you have
public int? Position { get; set; }
public string? position { get; set; }
public int? Position { get; set; }
public string? position { get; set; }
Does the serializer flip out or work with that?