I'd like an extension method to create an object based on another but keep only the primitive properties. This object will be dumped into a log file in JSON format for logging.
Based on the classes shown below, in this sample, the created object should keep only these properties :
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
I am using .NET Framework 4.7
How can I do this?
// To use like this
var order = new Order();
var forLog = order.RemovePrimitives();
// Sample of classes
public class Order
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public List<Item> Items { get; set; }
public Address Address { get; set; }
}
public class Item{}
public class Address{}
public static class Extensions
{
public static string RemovePrimitives(this object obj)
{
// I need to create an anonymous, named 'TheNewObjectHere' object but only with primitives
// I will dump the object to push to a log file. I need only primitives
return JsonConvert.SerializeObject(TheNewObjectHere, Formatting.Indented);
}
}
Thanks
CodePudding user response:
try this
public static class Extensions
{
public static string RemovePrimitives(this object obj)
{
var jsonObj = JObject.FromObject(obj);
var propToRemove = jsonObj.Properties().Where(i => !i.Value.GetType().ToString()
.Contains("JValue")).ToList();
foreach (var prop in propToRemove) prop.Remove();
return jsonObj.ToString();
}
}
CodePudding user response:
You can use reflection to get primitive properties and then use JObject
to build a JSON object dynamically.
public static readonly Type[] AdditionalPrimities = new[] { typeof(decimal), typeof(string) };
public static string RemovePrimitives<T>(this T obj)
{
var jObj = new JObject();
var props = GetPrimitiveProperties(obj);
foreach (var item in props)
{
var value = item.GetValue(obj);
if (value != null)
{
jObj.Add(item.Name, new JValue(value));
}
}
return jObj.ToString(Newtonsoft.Json.Formatting.Indented);
}
public static PropertyInfo[] GetPrimitiveProperties<T>()
{
var properties = typeof(T)
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(r => r.PropertyType.IsPrimitive || (r.PropertyType.IsGenericType && Nullable.GetUnderlyingType(r.PropertyType) != null) || AdditionalPrimities.Contains(r.PropertyType))
.Select(r => r)
.ToArray();
return properties;
}
public static void Main()
{
var order = new Order { FirstName = "abc", LastName = "cde", Address = new Address(), Age2 = 3, Age = 1 };
var final = order.RemovePrimitives();
Console.WriteLine(final);
}