From 493d48564587cd9878a02154fbe4d543d790261f Mon Sep 17 00:00:00 2001 From: manuc66 Date: Mon, 16 Apr 2018 23:48:07 +0200 Subject: [PATCH] now handle different type property name as suggested in #31 and #38 --- .../DemoKnownSubTypeWithProperty.cs | 13 ++ JsonSubTypes.Tests/JsonSubTypes.Tests.csproj | 1 + JsonSubTypes.Tests/TypePropertyCase.cs | 134 ++++++++++++++++++ JsonSubTypes/JsonSubtypes.cs | 24 +++- 4 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 JsonSubTypes.Tests/TypePropertyCase.cs diff --git a/JsonSubTypes.Tests/DemoKnownSubTypeWithProperty.cs b/JsonSubTypes.Tests/DemoKnownSubTypeWithProperty.cs index cdb6c08..dccc3a8 100644 --- a/JsonSubTypes.Tests/DemoKnownSubTypeWithProperty.cs +++ b/JsonSubTypes.Tests/DemoKnownSubTypeWithProperty.cs @@ -40,6 +40,19 @@ public void Demo() Assert.AreEqual("Painter", (persons.Last() as Artist)?.Skill); } + [Test] + public void DemoDifferentCase() + { + string json = "[{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," + + "{\"Department\":\"Department1\",\"JobTitle\":\"JobTitle1\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}," + + "{\"skill\"" + + ":\"Painter\",\"FirstName\":\"FirstName1\",\"LastName\":\"LastName1\"}]"; + + + var persons = JsonConvert.DeserializeObject>(json); + Assert.AreEqual("Painter", (persons.Last() as Artist)?.Skill); + } + [Test] public void FallBackToPArentWhenNotFound() { diff --git a/JsonSubTypes.Tests/JsonSubTypes.Tests.csproj b/JsonSubTypes.Tests/JsonSubTypes.Tests.csproj index 5f302a6..61a06fa 100644 --- a/JsonSubTypes.Tests/JsonSubTypes.Tests.csproj +++ b/JsonSubTypes.Tests/JsonSubTypes.Tests.csproj @@ -59,6 +59,7 @@ + diff --git a/JsonSubTypes.Tests/TypePropertyCase.cs b/JsonSubTypes.Tests/TypePropertyCase.cs new file mode 100644 index 0000000..3df1ceb --- /dev/null +++ b/JsonSubTypes.Tests/TypePropertyCase.cs @@ -0,0 +1,134 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using NUnit.Framework; + +namespace JsonSubTypes.Tests +{ + + public class TypePropertyCase + { + public class TypePropertyCase_LowerWithHigher + { + [JsonConverter(typeof(JsonSubtypes), "msgType")] + [JsonSubtypes.KnownSubType(typeof(Foo), 1)] + public abstract class DtoBase + { + public virtual int MsgType { get; set; } + } + + class Foo : DtoBase + { + } + + [Test] + public void FooParsingCamelCase() + { + var serializeObject = "{\"MsgType\":1}"; + var msgType = JsonConvert.DeserializeObject(serializeObject).MsgType; + Assert.AreEqual(1, msgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + + [Test] + public void FooParsingLowerPascalCase() + { + var serializeObject = "{\"msgType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + } + + public class TypePropertyCase_HigherWithLower + { + [JsonConverter(typeof(JsonSubtypes), "MsgType")] + [JsonSubtypes.KnownSubType(typeof(Foo), 1)] + public abstract class DtoBase + { + [JsonProperty("msgType")] + public virtual int MsgType { get; set; } + } + + class Foo : DtoBase + { + } + + [Test] + public void FooParsingCamelCase() + { + var serializeObject = "{\"MsgType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + + [Test] + public void FooParsingLowerPascalCase() + { + var serializeObject = "{\"msgType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + } + + public class TypePropertyCase_RedirectLowerWithHigher + { + [JsonConverter(typeof(JsonSubtypes), "messageType")] + [JsonSubtypes.KnownSubType(typeof(Foo), 1)] + public abstract class DtoBase + { + [JsonProperty("MessageType")] + public virtual int MsgType { get; set; } + } + + class Foo : DtoBase + { + } + + [Test] + public void FooParsingCamelCase() + { + var serializeObject = "{\"MessageType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + + [Test] + public void FooParsingLowerPascalCase() + { + var serializeObject = "{\"messageType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + } + + public class TypePropertyCase_RedirectHigherWithLower + { + [JsonConverter(typeof(JsonSubtypes), "MessageType")] + [JsonSubtypes.KnownSubType(typeof(Foo), 1)] + public abstract class DtoBase + { + [JsonProperty("messageType")] + public virtual int MsgType { get; set; } + } + + class Foo : DtoBase + { + } + + [Test] + public void FooParsingCamelCase() + { + var serializeObject = "{\"MessageType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + + [Test] + public void FooParsingLowerPascalCase() + { + var serializeObject = "{\"messageType\":1}"; + Assert.AreEqual(1, JsonConvert.DeserializeObject(serializeObject).MsgType); + Assert.IsInstanceOf(JsonConvert.DeserializeObject(serializeObject)); + } + } + } +} \ No newline at end of file diff --git a/JsonSubTypes/JsonSubtypes.cs b/JsonSubTypes/JsonSubtypes.cs index 9e4a680..c4ea18c 100644 --- a/JsonSubTypes/JsonSubtypes.cs +++ b/JsonSubTypes/JsonSubtypes.cs @@ -222,7 +222,7 @@ private static Type GetTypeByPropertyPresence(IDictionary jObjec .Select(knownType => { JToken ignore; - if (jObject.TryGetValue(knownType.PropertyName, out ignore)) + if (TryGetValueInJson(jObject, knownType.PropertyName, out ignore)) return knownType.SubType; return null; @@ -233,7 +233,7 @@ private static Type GetTypeByPropertyPresence(IDictionary jObjec private Type GetTypeFromDiscriminatorValue(IDictionary jObject, Type parentType) { JToken discriminatorToken; - if (!jObject.TryGetValue(TypeMappingPropertyName, out discriminatorToken)) + if (!TryGetValueInJson(jObject, TypeMappingPropertyName, out discriminatorToken)) return null; if (discriminatorToken.Type == JTokenType.Null) @@ -247,6 +247,26 @@ private Type GetTypeFromDiscriminatorValue(IDictionary jObject, return GetTypeByName(discriminatorToken.Value(), parentType); } + + private static bool TryGetValueInJson(IDictionary jObject, string propertyName, out JToken value) + { + if (jObject.TryGetValue(propertyName, out value)) + { + return true; + } + + var matchingProperty = jObject + .Keys + .FirstOrDefault(jsonProperty => string.Equals(jsonProperty, propertyName, StringComparison.OrdinalIgnoreCase)); + + if (matchingProperty == null) + { + return false; + } + + value = jObject[matchingProperty]; + return true; + } private static Type GetTypeByName(string typeName, Type parentType) {