Reputation: 603
I have a .Net Core 3.1 console application (not an ASP.NET Core) with SQL Server connection, where connection string is stored in appsettings.json file
{"ConnectionStrings": { "DefaultConnection":"Server=sqlserver;Database=appDb;User=username;Password=password;" }}
Previously I used Json.Net to read a string
var connString = JObject.Parse(File.ReadAllText("appsettings.json")).GetValue("ConnectionStrings").SelectToken("DefaultConnection").ToString()
and it worked fine. Now I decided to switch to System.Text.Json library and having issues with dynamic deserialization. The following code throws an exception:
var dict = JsonSerializer.Deserialize<Dictionary<string, string[]>>("appsettings.json");
System.Text.Json.JsonException: ''a' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.' Inner Exception JsonReaderException: 'a' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
Then I would read from a dictionary specifying Where Key == "ConnectionStrings", and then subsequent Value of string array == "DefaultConnection". I did not reach that point yet, because of an Exception, so I did not planned how to read from a Dictionary yet.
How can I use a new System.Text.Json library to read a connection string from appsettings.json file?
Is it correct to deserialize to Dictianory<string, string[]>
? Or it would be better to use Dictianory<string, Dictianory<string, string>>
?
Upvotes: 5
Views: 14482
Reputation: 22843
One of the benefits of System.Text.Json
is that it can easily and efficiently deserialize directly from a Stream
. When reading JSON from I/O such as a file or HTTP request, it's better to just deserialize the Stream
directly and avoid the unnecessary allocations and memory required to read it into a string first.
using var reader = new StreamReader("appsettings.json");
var dict = await JsonSerializer.DeserializeAsync<<Dictionary<string, string[]>>(reader.BaseStream);
That being said, for the specific case of reading the appsettings.json
, it's better to use the configuration tools built-in to the .NET Generic Host instead of manually parsing the JSON. This gives added benefits such as the ability to override these settings using environment variables and/or command line switches, as well as more easily moving them to another storage system such as KeyVault.
Upvotes: 7
Reputation: 1941
I've used the api in JsonDocument for this purpose:
var json = File.ReadAllText("appsettings.json");
var appSettings = JsonDocument.Parse(json, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip });
var result = appSettings.RootElement.GetProperty("ConnectionStrings").GetProperty("DefaultConnection").GetString();
HTH
Upvotes: 3
Reputation: 62472
JsonSerializer.Deserialize
expects a JSON string, not the name of a file.
You need to load the file into a string and then pass that to the Deserialize
method:
var json = File.ReadAllText("appsettings.json");
var dict = JsonSerializer.Deserialize<Dictionary<string, string[]>>(json);
Upvotes: 9