using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public int Id {get; set;}
[JsonProperty("emp_fname")]
public string Name {get;set;}
[JsonProperty("emp_lname")]
public string LastName {get;set;}
public string SomePropertyWithoutJsonPropertyAdded { get; set; }
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
public int Id {get; set;}
public string Name {get;set;}
public string LastName {get;set;}
[JsonProperty(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public string SomePropertyWithoutJsonPropertyAdded { get; set; }
public class DataContractType {
[DataMember(Name = "emp_id")]
public int Id {get; set;}
[DataMember(Name = "emp_fname")]
public string Name {get;set;}
[DataMember(Name = "emp_lname")]
public string LastName {get;set;}
public string SomePropertyWithoutJsonPropertyAdded { get; set; }
public static partial class JsonExtensions
static readonly IContractResolver defaultResolver = JsonSerializer.CreateDefault().ContractResolver;
public static object GetJsonProperty<T>(T obj, string jsonName, bool exact = false, IContractResolver resolver = null)
throw new ArgumentNullException(nameof(obj));
resolver = resolver ?? defaultResolver;
var contract = resolver.ResolveContract(obj.GetType()) as JsonObjectContract;
throw new ArgumentException(string.Format("{0} is not serialized as a JSON object", obj));
var property = contract.Properties.GetProperty(jsonName, exact ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
throw new ArgumentException(string.Format("Property {0} was not found.", jsonName));
return property.ValueProvider.GetValue(obj);
public static partial class JsonExtensions
public static string [] PropertyNames(Type type)
return PropertyNames(defaultResolver, type);
public static string [] PropertyNames(this IContractResolver resolver, Type type)
if (resolver == null || type == null)
throw new ArgumentNullException();
var contract = resolver.ResolveContract(type) as JsonObjectContract;
return contract.Properties.Where(p => !p.Ignored).Select(p => p.PropertyName).ToArray();
public static void Test()
var employee = new Employee
SomePropertyWithoutJsonPropertyAdded = "Some Property Without JsonProperty Added",
Console.WriteLine("Value of {0} is {1}.", "emp_lname",
JsonExtensions.GetJsonProperty(employee, "emp_lname"));
Console.WriteLine("Value of {0} is {1}.", "emp_lname",
JsonExtensions.GetJsonProperty(employee, "emp_lname", resolver : new CamelCasePropertyNamesContractResolver()));
Test(new SnakeCase { Id = 101, Name = "snake case name", LastName = "snake case last name" });
Test(new DataContractType { Id = 101, Name = "data member name", LastName = "data member last name", SomePropertyWithoutJsonPropertyAdded = "foo" });
static void Test<T>(T obj)
Console.WriteLine("\nTesting all properties of {0}:", obj);
foreach(var name in JsonExtensions.PropertyNames(obj.GetType()))
var value = JsonExtensions.GetJsonProperty(obj, name);
Console.WriteLine("Value of {0} is {1}", name, value);
Assert.IsTrue(new JTokenEqualityComparer().Equals(JObject.FromObject(obj)[name], value == null ? JValue.CreateNull() : JToken.FromObject(value)));
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];