Search code examples
c#dynamic

c# Populate Dynamic Object properties at runtime


Hopefully this is possible and straightforward. But I would like to dynamically populate the dynamic object at runtime so I can use a json schema generator (for a swagger file)

I have a list that I want to populate the object with. I.e each item in a list will be a property within the dynamic object.

This is the non adding dynamic properties way.

using Newtonsoft.Json.Schema;
                
public class Program
{
public static void Main()
{
    dynamic person = new
        {
            Id = 1,
            FirstName = "John",
            LastName = "Doe"
        };

        var schemaGenerator = new JsonSchemaGenerator { };

        var schema = schemaGenerator.Generate(person.GetType());

        Console.WriteLine(schema.ToString());
}
 }

But I would like to loop through a list or json and dynamically create properties in the person object.

I can't see how I can add properties to the person object after it's been created. This can be done with an Expando object, but expando doesn't work as expected with the Schema Generator.


Solution

  • If you want to add item(property) to exists object, you can look at aproved answer on this link

    if you want to understand benefits of ExpandoObject just open this url

    if you want to use ExpandoObject with Json Schema Generator you can check follow example

    using System.Dynamic;
    using Newtonsoft.Json.Schema;
    
    public class Program
    {
        public static void Main()
        {
            var properties = new[]
            {
                new { Name = "Id", Type = typeof(int) },
                new { Name = "FirstName", Type = typeof(string) },
                new { Name = "LastName", Type = typeof(string) },
            };
    
            dynamic person = new ExpandoObject();
            var personDict = (IDictionary<string, object>)person;
    
            foreach (var prop in properties)
            {
                personDict[prop.Name] = prop.Type.IsValueType ? Activator.CreateInstance(prop.Type) : Activator.CreateInstance(Type.GetType("System.String"), '\0', 0); ;
            }
    
            var schema = new JSchema { Type = JSchemaType.Object };
    
            foreach (var prop in personDict)
            {
                var propertySchema = new JSchema { Type = GetJSchemaType(prop.Value) };
                schema.Properties[prop.Key] = propertySchema;
            }
    
            var schemaJson = schema.ToString();
    
            Console.WriteLine(schemaJson);
        }
    
        private static JSchemaType GetJSchemaType(object value)
        {
            if (value == null)
                return JSchemaType.Null;
    
            var type = value.GetType();
    
            if (type == typeof(int))
                return JSchemaType.Integer;
            if (type == typeof(string))
                return JSchemaType.String;
            if (type == typeof(bool))
                return JSchemaType.Boolean;
            // Add more type mappings as needed
    
            return JSchemaType.None;
        }
    }