Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deserialize a json string or stream to Dictionary<string,string> with System.Text.Json

I'm getting a string of json as a stream and trying to deserialize it to a Dictionary<string, string> the problem with that is that it chokes on numbers, even when the serialize options are set. How does one do this with System.Text?

Program.cs with .NET 6:

using System;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;


Console.WriteLine("Converting Json...");
var result = await DeserializeJson();
Console.WriteLine($"result: {result}");


async Task<Dictionary<string, string>> DeserializeJson()
{
    var jsonText = "{\"number\": 709, \"message\": \"My message here\",\"bool\": true}";
    var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonText));

    var options = new JsonSerializerOptions 
    { 
         PropertyNameCaseInsensitive = true,
         NumberHandling = JsonNumberHandling.WriteAsString 
    };
    var fullResponse = await JsonSerializer.DeserializeAsync<Dictionary<string, string>>(stream, options);

    return fullResponse;
}

The main error that results:

---> System.InvalidOperationException: Cannot get the value of a token type 'Number' as a string.

This would make sense if it wasn't for the fact that I set the handle numbers property of the serialization options. Is that known to be failing or is something wrong here?

like image 763
CoderLee Avatar asked Feb 28 '26 13:02

CoderLee


1 Answers

Your json does not contain only strings. As a quick (but not performant one) fix you can try to deserealize to Dictionary<string, object> and then convert it to Dictionary<string, string>:

async Task<Dictionary<string, string>> DeserializeJson()
{
    var jsonText = "{\"number\": 709, \"message\": \"My message here\",\"bool\": true}";
    var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonText));

    var options = new JsonSerializerOptions 
    { 
        PropertyNameCaseInsensitive = true,
        NumberHandling = JsonNumberHandling.WriteAsString ,
        
    };
    var fullResponse = await JsonSerializer.DeserializeAsync<Dictionary<string, Object>>(stream, options);

    return fullResponse?.ToDictionary(pair => pair.Key, pair => pair.ToString());
}

Or parse the document manually:

async Task<Dictionary<string, string>> DeserializeJson()
{
    var jsonText = "{\"number\": 709, \"message\": \"My message here\",\"bool\": true}";
    var stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonText));
  
    using var jsonDocument = JsonDocument.Parse(stream);
    var dictionary = jsonDocument.RootElement
        .EnumerateObject()
        .ToDictionary(property => property.Name, property => property.Value.ToString());
    return dictionary;
}
like image 111
Guru Stron Avatar answered Mar 02 '26 01:03

Guru Stron



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!