Before anyone start suggesting any libraries like Newtonsoft.Json, System.Text.Json or whatever other nice and simple thing I would love to use, know that I am unable to use anything other than System.Json, because I am working within the constraints of an application, (I'm making a plugin), I have no influence over and has stopped active development, (it's an ERP system that only has security patches once per year, and feature requests result in passive-aggressive responses; even when I offered to do the changes myself free of charge).
I have some json, and some nice domain models, (objects, classes, models, entities, whatever you like to call public classes with properties), and I want them to get married. And using reflection is a pain when there are nesting.
Could anyone please show me some nice ways of doing this that does not require any nugets or dlls? All I'm finding when searching is related to all other libraries than System.Json.
Here's what I've been doing before I gave up, (I have refactored to something that looks like the use-case but that's because of contractual reasons):
public void BuildSettings(string settingsPath = "appsettings.json", params Type[] types)
{
if (!types.Any())
throw new ArgumentException("The type parameters cannot be empty", nameof(types));
var file = new FileInfo(settingsPath);
if (!file.Exists)
throw new ArgumentException($"No settings file found in the path '{settingsPath}'", nameof(settingsPath));
using (var reader = file.OpenText())
{
var rootJson = JsonValue.Load(reader);
if (rootJson.JsonType != JsonType.Object)
throw new ArgumentException($"The settings file must be a Json Object, but a '{rootJson.JsonType}' was found", nameof(settingsPath));
var jsonObject = rootJson as JsonObject;
if (jsonObject == null)
throw new NullReferenceException("The json object is null");
foreach (var type in types)
{
if (jsonObject.ContainsKey(type.Name))
{
var jsonSetting = jsonObject[type.Name] as JsonObject;
var properties = type.GetProperties();
foreach (var property in properties)
{
var value = jsonSetting[property.Name];
var propertyType = property.PropertyType;
property.SetValue();
// TODO: Ask StackOwerflow
}
}
}
}
}
There are some stupidity in this, but I don't make the rules
I guess you are in for some long hours... looks to me like you have to develop an ORM, I was faced with the same once where I had to make an ORM for ATM machines.
This code will not work for you as it assumes an IDataReader however you are in need of the property mapping using reflection and this code is in there.
Let me know if this get's you going as it has some optimisation in it for reusing reflected types etc.
I think you need to test for a property being a Class and create it using the activator and use an efficient cast using
Ido not know how my callses you need to support or if it is a fixed amount, you might just be after making a static T Parse(this T target, string json) method where you fragment the json string based on { and } brackets to get properties and [ and ] to get Arrays.
Here is the code for that, I used it for a VCARD Json parser I hade to make some time ago
Here is the full mapper I had to make where you see the mentioned reflection