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 static partial class JsonExtensions
public static T GetValueByUnderlyingName<T>(this JObject jObject, IContractResolver resolver, Type type, string underlyingName)
if (!resolver.TryGetJsonPropertyNameByUnderlyingName(type, underlyingName, out var jsonName))
throw new ArgumentException(underlyingName);
JToken versionToken = jObject.GetValue(jsonName);
if (versionToken is null)
throw new MandatoryPropertyMissingException(underlyingName);
return versionToken.Value<T>();
public static bool TryGetJsonPropertyByUnderlyingName(this IContractResolver resolver, Type type, string underlyingName, out JsonProperty property) =>
TryGetJsonPropertyByUnderlyingName(resolver, type, underlyingName, false, out property);
public static bool TryGetJsonPropertyByUnderlyingName(this IContractResolver resolver, Type type, string underlyingName, bool exact, out JsonProperty property)
resolver = resolver ?? throw new ArgumentNullException(nameof(resolver));
var contract = resolver.ResolveContract(type) as JsonObjectContract;
throw new ArgumentException();
foreach (var p in contract.Properties)
if (p.UnderlyingName == underlyingName)
if (property == null && string.Equals(p.UnderlyingName, underlyingName, StringComparison.OrdinalIgnoreCase))
public static bool TryGetJsonPropertyNameByUnderlyingName(this IContractResolver resolver, Type type, string underlyingName, out string jsonName) =>
TryGetJsonPropertyNameByUnderlyingName(resolver, type, underlyingName, false, out jsonName);
public static bool TryGetJsonPropertyNameByUnderlyingName(this IContractResolver resolver, Type type, string underlyingName, bool exact, out string jsonName)
if (resolver.TryGetJsonPropertyByUnderlyingName(type, underlyingName, exact, out var p))
jsonName = p.PropertyName;
public class MessageEnvelop
public int Version { get; set; }
public int FooBarProperty { get; set; }
[JsonProperty("ALLTYPES_NAME")]
public int AlltypesName { get; set; }
[JsonProperty("INFORMATION")]
public int Information { get; set; }
[JsonProperty("DECIMAL_DATA")]
public int DecimalInformation { get; set; }
public static void Test()
Test(new SnakeCaseNamingStrategy());
Test(new DefaultNamingStrategy());
Test(new CamelCaseNamingStrategy());
public static void Test(NamingStrategy strategy)
Console.WriteLine("Testing naming strategy {0}:", strategy);
var device = new MessageEnvelop
var resolver = new DefaultContractResolver
NamingStrategy = strategy,
var settings = new JsonSerializerSettings
ContractResolver = resolver,
var serializer = JsonSerializer.CreateDefault(settings);
var jObject = (JObject)JToken.FromObject(device, serializer);
var objectType = typeof(MessageEnvelop);
var version = jObject.GetValueByUnderlyingName<int>(serializer.ContractResolver, objectType, nameof(MessageEnvelop.Version));
Console.WriteLine("Version = {0}", version);
Assert.AreEqual(device.Version, version);
foreach (var property in objectType.GetProperties())
serializer.ContractResolver.TryGetJsonPropertyNameByUnderlyingName(objectType, property.Name, out var jsonName);
var value = jObject.GetValueByUnderlyingName<int>(serializer.ContractResolver, objectType, property.Name);
Console.WriteLine(" Name: {0}, JSON Name: {1}, Value = {2}", property.Name, jsonName,value);
Assert.AreEqual(property.GetValue(device), value);
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public class MandatoryPropertyMissingException : System.ArgumentException
public MandatoryPropertyMissingException() : base() { }
public MandatoryPropertyMissingException(string msg) : base(msg) { }