CSharp · Console
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
namespace RecursiveClassProperties
{
public static class Program
{
static void Main(string[] args)
{
var order = new Order()
{
Id = Guid.NewGuid(),
Customer = new Customer(Gender.Male, "John", "Smith", new List<string> { "Test" }),
Address = "12 Some Drive",
Postcode = "AB12 3CD",
Test = new List<string> { "Test1", "Test2" },
Test2 = new List<Test> { new Test("Test1"), new Test("Test2") }
};
var properties = GetAllProperties(order);
Console.WriteLine(JsonSerializer.Serialize(properties, new JsonSerializerOptions { WriteIndented = true }));
var formProperties = GetFormProperties(new Order());
formProperties["Customer.FirstName"].Value = "John";
formProperties["Customer.LastName"].Value = "Smith";
formProperties["Customer.Gender"].Value = "Male";
formProperties["Address"].Value = "12 Some Drive";
formProperties["Postcode"].Value = "AB12 3CD";
Console.WriteLine("\n");
Console.WriteLine(JsonSerializer.Serialize(formProperties, new JsonSerializerOptions { WriteIndented = true }));
var item = CreateItem(typeof(Order), formProperties);
Console.WriteLine("\n");
Console.WriteLine(JsonSerializer.Serialize(item, new JsonSerializerOptions { WriteIndented = true }));
}
private static object CreateItem(Type type, Dictionary<string, FormResponse> formProperties, object result = null, string parentName = null, bool isBase = false)
{
if (result is null)
{
result = Activator.CreateInstance(type);
isBase = true;
}
try
{
var properties = type.GetProperties();
foreach (var property in properties)
{
if (!Attribute.IsDefined(property, typeof(FormIgnoreAttribute)) && property.GetSetMethod() is not null)
{
if (property.PropertyType.Assembly == type.Assembly && !property.PropertyType.IsEnum)
{
var value = Activator.CreateInstance(property.PropertyType);
type.GetProperty(property.Name).SetValue(result, value);
CreateItem(property.PropertyType, formProperties, result);
}
else
{
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(decimal) || property.PropertyType == typeof(string) || property.PropertyType.IsEnum || property.PropertyType == typeof(Guid))
{
if (property.PropertyType.IsEnum)
{
if (isBase)
{
var enumValue = Enum.Parse(property.PropertyType, formProperties[property.Name].Value);
type.GetProperty(property.Name).SetValue(result, enumValue);
}
else
{
var filteredProperties = formProperties.Where(formProperty => type.Name == formProperty.Key.Split('.')[..^1].FirstOrDefault() && property.Name == formProperty.Key.Split('.').Last());
if (filteredProperties.Any())
{
var itemProperties = filteredProperties.FirstOrDefault();
var enumValue = Enum.Parse(property.PropertyType, itemProperties.Value.Value);
var item = result.GetType().GetProperty(type.Name).GetValue(result);
type.GetProperty(property.Name).SetValue(item, enumValue);
}
}
}
else
{
if (isBase)
{
if (property.PropertyType == typeof(Guid)) type.GetProperty(property.Name).SetValue(result, Guid.NewGuid());
else type.GetProperty(property.Name).SetValue(result, formProperties[property.Name].Value);
}
else
{
var filteredProperties = formProperties.Where(formProperty => type.Name == formProperty.Key.Split('.')[..^1].FirstOrDefault() && property.Name == formProperty.Key.Split('.').Last());
if (filteredProperties.Any())
{
var itemProperties = filteredProperties.FirstOrDefault();
var item = result.GetType().GetProperty(type.Name).GetValue(result);
type.GetProperty(property.Name).SetValue(item, itemProperties.Value.Value);
}
}
}
}
}
}
}
}
catch { return result; }
return result;
}
private static Dictionary<string, FormResponse> GetFormProperties(object @object) => GetAllProperties(@object).ToDictionary(x => x.Key, x => new FormResponse(string.Empty));
private static Dictionary<string, string> GetAllProperties(object @object, Dictionary<string, string> result = null, Type activationType = null)
{
void AddResult(string property, string value, bool isBase)
{
if (isBase) result.Add(property, value);
else result.Add($"{@object.GetType().Name}.{property}", value);
}
var isBase = default(bool);
if (result is null)
{
result = new Dictionary<string, string>();
isBase = true;
}
if (@object is null && !isBase) @object = Activator.CreateInstance(activationType);
else if (@object == null || @object.GetType().IsPrimitive) return result;
try
{
var type = @object.GetType();
var properties = type.GetProperties();
foreach (var property in properties)
{
Console.WriteLine(property.Name);
if (!Attribute.IsDefined(property, typeof(FormIgnoreAttribute)))
{
var value = property.GetValue(@object, null);
if (value is IList items)
{
foreach (var item in items)
{
var itemType = item.GetType();
if (itemType.IsPrimitive || itemType == typeof(decimal) || itemType == typeof(string) || itemType.IsEnum || itemType == typeof(Guid))
{
var list = new string[items.Count];
items.CopyTo(list, 0);
var joined = string.Join("||", list);
AddResult(property.Name, joined, isBase);
}
else GetAllProperties(item, result);
}
}
else
{
if (property.PropertyType.Assembly == type.Assembly && !property.PropertyType.IsEnum)
{
if (value is null) GetAllProperties(value, result, property.PropertyType);
else GetAllProperties(value, result);
}
else
{
if (value is null) AddResult(property.Name, string.Empty, isBase);
else
{
var valueType = value.GetType();
if (valueType.IsPrimitive || valueType == typeof(decimal) || valueType == typeof(string) || valueType.IsEnum || valueType == typeof(Guid))
{
if (valueType.IsEnum)
{
var enumValue = Enum.GetName(valueType, value);
AddResult(property.Name, enumValue.ToString(), isBase);
}
else AddResult(property.Name, value.ToString(), isBase);
}
}
}
}
}
}
}
catch { return result; }
return result;
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public class FormIgnoreAttribute : Attribute { }
public class FormResponse
{
public FormResponse(string value) => Value = value;
public string Value { get; set; }
}
public class Order
{
public Guid Id { get; set; }
public Customer Customer { get; set; }
public string Address { get; set; }
public string Postcode { get; set; }
public List<string> Test { get; set; }
public List<Test> Test2 { get; set; }
}
public class Test
{
public Test(string value) => Value = value;
public string Value { get; set; }
}
public enum Gender
{
Male,
Female
}
public class Customer
{
public Customer() { }
public Customer(Gender gender, string firstName, string lastName, List<string> test)
{
Gender = gender;
FirstName = firstName;
LastName = lastName;
Test = test;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName => $"{FirstName} {LastName}";
public Gender Gender { get; set; }
public List<string> Test { get; set; }
}
}