How to add C# class unique instance object to a List<objects>at runtime?


Overview

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"
			}
		}
	}	 
}

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; } 
   }

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; }
   }

  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;
   }

Prepare the Class Models with Values

Create a class example JsonMapper.cs  and add the following code 


JsonMapper.cs

Add a int property _iCount  and initialize to 1. This count helps incrementing "e.1.{_iCount}" instance

 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.
      } 

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 


The second line creating a class instance with models values, again this is for single entity construct logic for looping.

The third line create a dictionary<string,class> string represents  the first line of code result and class is E1 model class created in above model

The fourth line to add dictionary object to a JsonMapper class instance.

The fifth line to serialize class model to JSON output  How to serialize model class to JSON?

 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.
      } 
   }

Execute Code

This is the JSON result for adding single class instance to a dictionary collection.  

jsonconvert.serializeobject c#

JSON Format

Summary

To add  C# class unique instance object to a List<class> at runtime,  with the help of  Dictionary<string,class> to add in main class solve the problem.

This article explained the JSON structure of generating dynamic class instances. So keeping JSON output in mind we created class models and Class DisplayName Attributes,  Json Property Attributes and then JsonIgnore attributes with conditions applied. 

Created a JsonMapper.cs class helps adding values to model class and converting to JSON.

The main purpose for this article is to show the easy way of adding Dictionary<string,class> to solve adding dynamic class instance.