Home > Back-end >  Reading a json file asynchronously, the object property results are always null
Reading a json file asynchronously, the object property results are always null

Time:12-04

I have a Json file, it contains connectionstring. I want to asynchronously read the file and deserialize it to a ConnectionString object and I always get a null result. I'm using .NET Core 6 and System.Text.Json.

Here is contents of my Json file:

{
    "ConnectionStrings": {
        "ConnStr": "Data Source=(local);Initial Catalog=MyData;Integrated Security=False;TrustServerCertificate=True;Persist Security Info=False;Async=True;MultipleActiveResultSets=true;User ID=sa;Password=MySecret;",
        "ProviderName": "SQLServer"
    }
}

Here are the contents of my classes:

internal class DBConnectionString
{
    [JsonPropertyName("ConnStr")]
    public string ConnStr { get; set; }
    [JsonPropertyName("ProviderName")]
    public string ProviderName { get; set; }

    public DBConnectionString()
    {

    }
}



public class DBConnStr {
    private static string AppSettingFilePath => "appsettings.json";

    public static async Task<string> GetConnectionStringAsync()
    {
        string connStr = "";

        if (File.Exists((DBConnStr.AppSettingFilePath)))
        {
            using (FileStream sr = new FileStream(AppSettingFilePath, FileMode.Open, FileAccess.Read))
            {
                //string json = await sr.ReadToEndAsync();

                System.Text.Json.JsonDocumentOptions docOpt = new System.Text.Json.JsonDocumentOptions() { AllowTrailingCommas = true };

                using (var document = await System.Text.Json.JsonDocument.ParseAsync(sr, docOpt))
                {
                    System.Text.Json.JsonSerializerOptions opt = new System.Text.Json.JsonSerializerOptions() { AllowTrailingCommas = true, PropertyNameCaseInsensitive = true };

                    System.Text.Json.JsonElement root = document.RootElement;
                    System.Text.Json.JsonElement element = root.GetProperty("ConnectionStrings");

                    sr.Position = 0;

                    var dbConStr = await System.Text.Json.JsonSerializer.DeserializeAsync<DBConnectionString>(sr, opt);

                    if (dbConStr != null)
                    {
                        connStr = dbConStr.ConnStr;
                    }
                }
            }
        }

        return connStr;
    }
}

The following is the syntax that I use to call the GetConnectionStringAsync method:

string ConnectionString = DBConnStr.GetConnectionStringAsync().Result;

When the application is running in debug mode, I checked, on line

var dbConStr = await System.Text.Json.JsonSerializer.DeserializeAsync(sr, opt);

The DBConnectionString object property is always empty.

I also tried the reference on the Microsoft website, https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/how-to?pivots=dotnet-6-0 but it doesn't work succeed.

using System.Text.Json;

namespace DeserializeFromFileAsync
{
    public class WeatherForecast
    {
        public DateTimeOffset Date { get; set; }
        public int TemperatureCelsius { get; set; }
        public string? Summary { get; set; }
    }

    public class Program
    {
        public static async Task Main()
        {
            string fileName = "WeatherForecast.json";
            using FileStream openStream = File.OpenRead(fileName);
            WeatherForecast? weatherForecast = 
                await JsonSerializer.DeserializeAsync<WeatherForecast>(openStream);

            Console.WriteLine($"Date: {weatherForecast?.Date}");
            Console.WriteLine($"TemperatureCelsius: {weatherForecast?.TemperatureCelsius}");
            Console.WriteLine($"Summary: {weatherForecast?.Summary}");
        }
    }
}

Do you have a solution for my problem or a better solution? I appreciate all your help. Thanks

Sorry about my English if it's not good, because I'm not fluent in English and use google translate to translate it

CodePudding user response:

To begin with, if you want to read information from appSettings.json, you should explore more into reading configurations. There are helper classes provided by .Net for the same.

Coming back to your code, if you want to use your own code for Json Deserialization, then you need to make the following change to it.

var dbConStr = System.Text.Json.JsonSerializer.Deserialize<DBConnectionString>(element.GetRawText(), opt);

where, element according to code shared in the question is defined as

System.Text.Json.JsonElement element = root.GetProperty("ConnectionStrings");

This ensures the Raw Json associated with the JsonElement ConnectStrings is de-serialized.

However, I recommend you to read more into Reading configurations using the IConfiguration and related .Net helpers.

CodePudding user response:

There are a few issues with the code you've provided. Firstly, the DBConnectionString class is missing the JsonPropertyName attribute on the ConnStr property. This attribute is necessary for the System.Text.Json serializer to correctly map the property to the corresponding JSON property. You should update your class as follows:

internal class DBConnectionString
{
    [JsonPropertyName("ConnStr")]
    public string ConnStr { get; set; }

    [JsonPropertyName("ProviderName")]
    public string ProviderName { get; set; }

    public DBConnectionString()
    {

    }
}

Secondly, you're trying to deserialize the JSON file twice. In the first case, you're using the JsonDocument class to get the ConnectionStrings property of the root element and then you're trying to deserialize the entire JSON file again to a DBConnectionString object. Instead, you should simply deserialize the ConnectionStrings property to a DBConnectionString object directly, like this:

System.Text.Json.JsonSerializerOptions opt = new System.Text.Json.JsonSerializerOptions() { AllowTrailingCommas = true, PropertyNameCaseInsensitive = true };

System.Text.Json.JsonElement root = document.RootElement;
System.Text.Json.JsonElement element = root.GetProperty("ConnectionStrings");

var dbConStr = System.Text.Json.JsonSerializer.Deserialize<DBConnectionString>(element.ToString(), opt);

With these changes, your code should work correctly and you should be able to deserialize the JSON file to a DBConnectionString object as expected.

  • Related