How to add C# class unique instance object to a List<objects>at runtime?
This is obvious to get errors and improvements while development. I encountered a scenario in where to create a dynamic list of object in C# class that generates expected JSON result as output.
This article explains how a list of classes can be added in a class that produces the result wanted. I have a end-result JSON output format must represent in C# class.
Tips know more...
If you are new to JSON conversion stuff check this out these two, one is "Paste JSON as Code" provides Visual Studio extension for quick help Quick Type . The other one is conversion to multiple sources such as can easily convert JSON to C#, JSON to Java, XML to C#, XML to Java JSON2CSharp
What is the end result JSON Structure?
C# code should be able to produce JSON structure as an end result.
Please note that under "facts" section contains a class "e.1.1", "e.1.2" and "e.1.3" as goes by N number of classes added dynamically.
JSON Result
{
"facts":
{
"e.1.1":
{
"Value":"43431",
"Dimensions":
{
"Concept":"A",
"Entity":"Ae",
"Period":"Ap"
}
},
"e.1.2":
{
"Value":"23232",
"Dimensions":
{
"Concept":"B",
"Entity":"Be",
"Period":"Bp"
}
}
}
}
{
"facts":
{
"e.1.1":
{
"Value":"43431",
"Dimensions":
{
"Concept":"A",
"Entity":"Ae",
"Period":"Ap"
}
},
"e.1.2":
{
"Value":"23232",
"Dimensions":
{
"Concept":"B",
"Entity":"Be",
"Period":"Bp"
}
}
}
}
Create a class model for JSON in C#
Solution
For the above JSON structure for adding a list of classes dynamically using Dictionary
Add a dictionary property to a class that contains <string, class>
Add a attribute [JsonProperty("facts")] for property which helps camel case in JSON result
Root Class model
public class Root
{
[JsonProperty("facts")]
public Dictionary<string, E1> Facts { get; set; }
}
public class Root
{
[JsonProperty("facts")]
public Dictionary<string, E1> Facts { get; set; }
}
E1 Class model
For this class note that I have added class attribute called [DisplayName("e.1.")] this helps to ease JSON result as expected.
If you see the second property of this class has an attribute set as
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
JsonIgnore will ignore this property when converting class to JSON, and it is important to know that on what condition the property should be ignored. How to ignore property when converting JSON?
[DisplayName("e.1.")]
public class E1
{
[JsonProperty("value")]
public string Value { get; set; }
[JsonProperty("decimals")]
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Decimals { get; set; } = null;
[JsonProperty("dimensions")]
public Dimensions Dimensions { get; set; }
}
[DisplayName("e.1.")]
public class E1
{
[JsonProperty("value")]
public string Value { get; set; }
[JsonProperty("decimals")]
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Decimals { get; set; } = null;
[JsonProperty("dimensions")]
public Dimensions Dimensions { get; set; }
}
Dimensions Class model
public class Dimensions
{
[JsonProperty("concept")]
public string Concept { get; set; }
[JsonProperty("entity")]
public string Entity { get; set; }
[JsonProperty("period")]
public string Period { get; set; }
[JsonProperty("unit")]
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Unit { get; set; } = null;
}
public class Dimensions
{
[JsonProperty("concept")]
public string Concept { get; set; }
[JsonProperty("entity")]
public string Entity { get; set; }
[JsonProperty("period")]
public string Period { get; set; }
[JsonProperty("unit")]
[System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string Unit { get; set; } = null;
}
Prepare the Class Models with Values
Create a class example JsonMapper.cs
and add the following code
JsonMapper.cs
and add the following code JsonMapper.cs
public class JsonMapper
{
private static int _iCount = 1;
}
public class JsonMapper
{
private static int _iCount = 1;
}
Add a private method in the same JsonMapper.cs class. This method helps to return our class model display name attribute defined as "e.1." instance
private string GetClassDisplayAttributeName()
{
// get class attribute display name
var classAliasName = typeof(E1)
.CustomAttributes.FirstOrDefault()
?.ConstructorArguments.FirstOrDefault()
.Value;
return classAliasName.ToString(); // returns class atrribute displayname e.1.
}
private string GetClassDisplayAttributeName()
{
// get class attribute display name
var classAliasName = typeof(E1)
.CustomAttributes.FirstOrDefault()
?.ConstructorArguments.FirstOrDefault()
.Value;
return classAliasName.ToString(); // returns class atrribute displayname e.1.
}
Create a Test Method
Add a method called Test() in the same JsonMapper.cs class
The first line of code returns result of "e.1.1"
please note that this class helps for adding single entity, if you need to add in a collection of classes to generate "e.1.1", "e.1.2" ,"e.1.3" create your own looping logic
public void Test()
{
var classInstanceName = $"{GetClassDisplayAttributeName()}{_iCount++}"; //returns e.1.1
var item1 = new E1
{
Decimals = null,
Value = "1",
Dimensions = new Dimensions
{
Concept = "A",
Entity = "Ae",
Period = "Ap",
Unit = null
}
};
Dictionary<string, E1> dicFacts = new Dictionary<string, E1>();
dicFacts.Add(classInstanceName, item1);
var clsObj = new XbrlJsonModel()
{
Facts = dicFacts
};
var jsonResult= JsonConvert.SerializeObject(clsObj);
}
public void Test()
{
var classInstanceName = $"{GetClassDisplayAttributeName()}{_iCount++}"; //returns e.1.1
var item1 = new E1
{
Decimals = null,
Value = "1",
Dimensions = new Dimensions
{
Concept = "A",
Entity = "Ae",
Period = "Ap",
Unit = null
}
};
Dictionary<string, E1> dicFacts = new Dictionary<string, E1>();
dicFacts.Add(classInstanceName, item1);
var clsObj = new XbrlJsonModel()
{
Facts = dicFacts
};
var jsonResult= JsonConvert.SerializeObject(clsObj);
}
Complete C# Code
JsonMapper.cs
public class JsonMapper
{
private static int _iCount = 1;
public void Test()
{
var classInstanceName = $"{GetClassDisplayAttributeName()}{_iCount++}"; //returns e.1.1
var item1 = new E1
{
Decimals = null,
Value = "1",
Dimensions = new Dimensions
{
Concept = "A",
Entity = "Ae",
Period = "Ap",
Unit = null
}
};
Dictionary<string, E1> dicFacts = new Dictionary<string, E1>();
dicFacts.Add(classInstanceName, item1);
var clsObj = new XbrlJsonModel()
{
Facts = dicFacts
};
var jsonResult= JsonConvert.SerializeObject(clsObj);
}
private string GetClassDisplayAttributeName()
{
// get class attribute display name
var classAliasName = typeof(E1)
.CustomAttributes.FirstOrDefault()
?.ConstructorArguments.FirstOrDefault()
.Value;
return classAliasName.ToString(); // returns class atrribute displayname e.1.
}
}
public class JsonMapper
{
private static int _iCount = 1;
public void Test()
{
var classInstanceName = $"{GetClassDisplayAttributeName()}{_iCount++}"; //returns e.1.1
var item1 = new E1
{
Decimals = null,
Value = "1",
Dimensions = new Dimensions
{
Concept = "A",
Entity = "Ae",
Period = "Ap",
Unit = null
}
};
Dictionary<string, E1> dicFacts = new Dictionary<string, E1>();
dicFacts.Add(classInstanceName, item1);
var clsObj = new XbrlJsonModel()
{
Facts = dicFacts
};
var jsonResult= JsonConvert.SerializeObject(clsObj);
}
private string GetClassDisplayAttributeName()
{
// get class attribute display name
var classAliasName = typeof(E1)
.CustomAttributes.FirstOrDefault()
?.ConstructorArguments.FirstOrDefault()
.Value;
return classAliasName.ToString(); // returns class atrribute displayname e.1.
}
}
0 Comments