❔ Reading from a JSON file
I have a JSON file in the following format
where I don't know how many
type
s I have or how many path
s per type.
How would I go about reading and storing this in C#?92 Replies
Or is there a different way that I could format this json file that retains the same information?
You could probably use a
Dictionary<string, Dictionary<string, string>>
I'm at the point where I have the StreamReader for the json,
would I deserialize it like this?
at this point it's getting confusing to me
i would use
JsonElement
and alike as explained here: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/handle-overflow?pivots=dotnet-7-0How to handle overflow JSON or use JsonElement or JsonNode in Syste...
Learn how to handle overflow JSON or use JsonElement or JsonNode while using System.Text.Json to serialize and deserialize JSON in .NET.
you would want to avoid newtonsoft
ok so.. as far as I'm reading, I can deserialize into a JsonElement object and go from there? How do I get values out of that?
that's it
and then you do
dict[/* type */][/* path */]
it has a lot of different
Get...
methods for the different types.
if its really just that structure (no deeper nesting) and everything is a string
, i would also go for that dictionary approach
basically what Ero said ;pI'm getting
at line 3?
.
where are you getting your JsonSerializer then?
if I uninstall newtonsoft it doesn't recognize it
import
using System.Text.Json
and remove Newtonsoft
@Ero uses the JsonSerializer from that said namespace because its not part of a third party lib but instead part of the .Net Class Libraryand much better ;p (personal opinion)
not an opinion
afaik Netwonsoft is still better in performance but I guess performance is not very important. Its more important that you wanna use builtin stuff rather than maintaining dependencies to nuget packages
what
imagine thinking newtonsoft is faster
okay so apparently System.Text.Json has caught up in .net 7
good to know, thx
I was using System.Text.Json anway
cuz of this
STJ uses source code generation nowadays, iirc Newtonsoft still uses reflection
not sure if this benchmark uses the codegen
well they advertise with being more performant than .Net's builtin serializer
well, if not, it would just mean that it would even widen the gap in performance ;p
but seems its not the case anymore
afaik prior to 7 that was the case
yep
that seemed to work! thanks everyone
glad we could help o7
funniest thing is that some of newtonsoft doesn't use the generic overloads
so you deserialize into
dynamic
which will hurt other parts of your code
not just the deserializationits even in the subtitle of the linked article ;p
Did Microsoft finally catch up?
I always wondered why people would ever choose to use
dynamic
🤷 even if not using Generics you might rather deserialize to object
tho?
why throw away the typesystemit's difficult to rationalize, but there are some use cases
but the code that gets compiled in place of
dynamic
ismy general rule of thumb: Pref Generics over object and pref object over dynamic. I haven't faced a use case where I had to use dynamic yet
well, see for yourself
tbh, i dunno much about
dynamic
, never even wanted to touch it as it cant be good just from name ;pyou mean in IL? I Will have a look
not even
wdym then
lets move this somewhere else instead of abusing this help thread
If you can change your JSON file format, use an array of paths.
unless I’m misunderstanding somehow, that doesn’t preserve the “type” information, and the path isn’t the path to the filename, I can’t combine them.
That's beside the point, I'm talking about how you should use the values, I'm talking about how to format your JSON in order to support a more complex structure.
???
how does that support a more complex structure? an array of strings is simpler and doesn’t have as much information.
how tf is it besides the point when your solution doesn’t contain the information that I need?
www.javatpoint.com
JSON Array - javatpoint
JSON Array for beginners and professionals with examples of JSON with java, json array of string, json array of numbers, json array of booleans, json srray of objects, json multidimentional array. Learn JSON array example with object, array, schema, encode, decode, file, date etc.
You might want to use an array of objects instead of array of strings.
what’s the benefit of using an array of objects over a dictionary of objects
You can map that to a class.
STJ works really well with classes.
As in, instead of having to manually process JSON properties and values, you can serialize/deserialize an entire file with a single call.
well, I am still doing it in one call as a dictionary of dictionaries, right?
is the
path
, path2
, etc information important?
if not u can simply restructure it to
or even drop the paths
property.
can u tell more about the information itself?
or more detailed example datathe paths can have different filenames associated with each path.
I’m actually on my phone by now, tbh. I got a working solution a while ago.
so one path can have multiple file names or just one?
each path is associated with one file, though the same file may have multiple paths.
I guess i could flip it so that i have a file as a key and an array of paths as the value
but it doesn’t really seem to reduce the complexity by much
well, depends on what u want to do with the data afterwards.
if u want to find possible paths for a given filename flip it, if u want it the file name for a given path keep it as is, if u want both it doesnt really matter
in such situations i usually first work out a class hierarchy i wanna work with in code and then the json comes naturally ;p
i need all of the keyvalue pairs so I guess I could make them tuples if I really wanted to shrugs
I’m practically iterating through the dictionary under each type so whatever works works. so
you can do the same thing with Dictionary 🤔 or am I missunderstanding something? All you'd have to do for this deserialization to work is modify the json slightly so that it has a wrapper object and a field called "types": holding all the content (which you would also have to do when using array or list or any other datastructure as a property here)
if you wanted to switch to an array but also keep the type information, you could make a field out of it:
but again, if we wanna map that to a type, its missing the wrapper object and "types" field holding the array, same thing as with Dictionary
u couldnt really map it like that, would have to have another nesting, because there is an unknown amount of paths
I don't see what you mean. we can deserialize this to a collection of dictionaries as we did before. I just replaced the outer dictionary with a List/Array
and I did mention that you need another wrapper object to deserialize the json to a concrete custom type if thats what you mean by "another nesting"
i mean that part:
the
type
is actually another hierarchy level by what OP explained.
wiring that into some DTO would mean that u need a custom (de-)serializerhierarchy level by what OP explained.the hierarchy is our choice. We design and structure our data for our needs
wiring that into some DTO would mean that u need a custom (de-)serializer
its litteraly just an additional key-valu pair in the dictionary
there is no extra work
JsonSerializer.Deserialize<FooBarDTO>(fs)
but the structure is
the type is grouping the path<->filename stuff
yep, just like in my suggestion...
I am grouping path and filename, I just pref using Dictionary over List of tuples...
and where goes the type value info?
???
well, most likely it would be better to have some kind hashset or so
looking at the original post there are different named types, how do u reflect that in ur
FooBarDTO
?good point, so I would also encapsulate the Dictionary<string, string> into its own TypeDTO and add a name property, just not using list of tuples
in the end i think about this sturcture more or letss:
naming might be wrong tho
looks great 😊
but I think as you had before with name on the inner type and List of tuples made more sense
I'd go with:
then
from the explanation i would go with that and
because from the explanation it seems that the type is relevant (thus its name),
the other is a 1:1 binding (because they iterate over it all so it just has to be unique)
to have it without custom implementations.
urs makes sense too ofc
i guess we just simply do not have enough information and are wildly guessing
issue I see with this approach here is that you would have to create a third record that holds
ISet<TypeMappings> Types
because author of thread said he doesnt know how many types there are. Now you've created three types when we only ever wanted to deserialize a collection of objectsbecause the iteration part i thought that the deserialization type would be
TypeMappings[]
or list, or whatever kind of collection it should be
its hard to tell whats correct because neither the json structure nor the poco structure is definedInstead of trying to adjust JSON file format and contents, all you need to do is design a class that will hold your data and them simply use STJ to (de)serialize it.
the author said he is free to adjust the json file format and contents, so why not play around with ideas what would be the best design to structure it?
Sure, but I like simple solutions 👀
well I like good design, even if it takes more time
Yeah, but overthinking is also a bad thing.
thats the point, we dont even know exactly what its used for, so we have neither nor ;p
truuee
we r just imagining possible solutions here
I've worked with JSON enough to know what works best in most cases.
And since OP is going to use STJ, focusing on class rather than the underlying JSON is the key.
but the class design and the json design go hand in hand
so in order to design good classes we gotta design good json first, no?
the info we have:
there are some kind of types
types have a collection of relation between paths and file names
over these relations will be iterated
thats it
edit: json and class structure can be adjusted
ofc we can yeet everyting into FooBarDTO
but that won't do us a favor
Yes, because you only need to design the class ...
we dont have the full knowledge about what happens with the data, thus we cant construct the pocos optimal
The way I see it
- Create a class
- Serialize it
- Check if resulting JSON is good for your use-case
- If not, adjust the class and try again
but he is not serializing he is deserializing. He receives json and he said he can modify the shape of json he receives
so we start designing the json
right?
and then classes
i think they do both, but dont have a clear design in mind.
thus we need more info about the use case, which isnt clear yet
with the limited info we have been given we designed some nice structures, i guess its time that the OP steps in and tells us what they want to achieve ;p
@PracticalPotato i guess we need ur input ⤴️ xD
I seem to have nerd sniped the C# community.
honestly, all of these seem plausible, depending on use case. the only thing that seems constant is that if I don't know how many values I will have, I should shove it into a dictionary.
The "type" is the name of a program that has many different versions. The path is a path to a registry key in the Windows uninstall registry. I'm using this registry key in order to find the location where the program is installed. Then, I use the name of the executable to start the program.
the json structure that I posted originally was just what made the most sense to me.
I wanted to be able to select a "type" and then my program will try each registry key, and when it's found, open the .exe
Why use Dictionary when you have arrays?
Yes, you can, but why complicate things?
A simple array of strings will satisfy your need.
Because, as far as I understand your requirement, you don't need to know whether something is
path
or path22
or path122
, you just need to get all paths as some kind of list and process them all. This is why an array is best fit because it's simple. Dictionary is OK, but IMO it is an overkill for this use-case. That's all.
Dictionary stores key-value pairs.
If I'm not mistaking, you only need the values, and you don't care much for the keys.
However, if you do need to know which key a particular value belongs to, that's different, but what you explained above doesn't suggest that, which is why I still recommend a simple array of strings.
Personally, I would just use a List<string>
and be done with it, because STJ knows how to serialize that.Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.