From 8eea549b0a43809b3c6f24b9009b785ad5d27a79 Mon Sep 17 00:00:00 2001 From: Tamizhvendan S Date: Fri, 19 Sep 2014 22:31:29 +0530 Subject: [PATCH] Removing the redundant requirement of having "fields property with empty array" for union types with no values. Note : Values are optionals in the Discriminated Union Reference : http://msdn.microsoft.com/en-us/library/vstudio/dd233226(v=vs.100).aspx --- .../DiscriminatedUnionConverterTests.cs | 12 ++----- .../Converters/DiscriminatedUnionConverter.cs | 35 ++++++++++++------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Converters/DiscriminatedUnionConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DiscriminatedUnionConverterTests.cs index daf55524..d3315de7 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DiscriminatedUnionConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DiscriminatedUnionConverterTests.cs @@ -42,7 +42,7 @@ namespace Newtonsoft.Json.Tests.Converters { string json = JsonConvert.SerializeObject(Currency.AUD); - Assert.AreEqual(@"{""Case"":""AUD"",""Fields"":[]}", json); + Assert.AreEqual(@"{""Case"":""AUD""}", json); } [Test] @@ -56,10 +56,10 @@ namespace Newtonsoft.Json.Tests.Converters [Test] public void DeserializeBasicUnion() { - Currency c = JsonConvert.DeserializeObject(@"{""Case"":""AUD"",""Fields"":[]}"); + Currency c = JsonConvert.DeserializeObject(@"{""Case"":""AUD""}"); Assert.AreEqual(Currency.AUD, c); - c = JsonConvert.DeserializeObject(@"{""Fields"":[],""Case"":""EUR""}"); + c = JsonConvert.DeserializeObject(@"{""Case"":""EUR""}"); Assert.AreEqual(Currency.EUR, c); c = JsonConvert.DeserializeObject(@"null"); @@ -96,12 +96,6 @@ namespace Newtonsoft.Json.Tests.Converters ExceptionAssert.Throws(() => JsonConvert.DeserializeObject(@"{""Fields"":[1]}"), "No 'Case' property with union name found. Path '', line 1, position 14."); } - [Test] - public void DeserializeBasicUnion_NoFields() - { - ExceptionAssert.Throws(() => JsonConvert.DeserializeObject(@"{""Case"":""AUD""}"), "No 'Fields' property with union fields found. Path '', line 1, position 14."); - } - [Test] public void DeserializeBasicUnion_UnexpectedEnd() { diff --git a/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs b/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs index 3ab1469c..b9566a67 100644 --- a/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DiscriminatedUnionConverter.cs @@ -65,12 +65,16 @@ namespace Newtonsoft.Json.Converters object info = FSharpUtils.GetUnionCaseInfo(result); object fields = FSharpUtils.GetUnionCaseFields(result); object caseName = FSharpUtils.GetUnionCaseInfoName(info); + object[] fieldsAsArray = fields as object[]; writer.WriteStartObject(); writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(CasePropertyName) : CasePropertyName); writer.WriteValue((string)caseName); - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(FieldsPropertyName) : FieldsPropertyName); - serializer.Serialize(writer, fields); + if (fieldsAsArray != null && fieldsAsArray.Length > 0) + { + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(FieldsPropertyName) : FieldsPropertyName); + serializer.Serialize(writer, fields); + } writer.WriteEndObject(); } @@ -135,21 +139,26 @@ namespace Newtonsoft.Json.Converters if (matchingCaseInfo == null) throw JsonSerializationException.Create(reader, "No '{0}' property with union name found.".FormatWith(CultureInfo.InvariantCulture, CasePropertyName)); - if (fields == null) + + PropertyInfo[] fieldProperties = (PropertyInfo[])FSharpUtils.GetUnionCaseInfoFields(matchingCaseInfo); + object[] typedFieldValues = new object[fieldProperties.Length]; + + if (fieldProperties.Length > 0 && fields == null) throw JsonSerializationException.Create(reader, "No '{0}' property with union fields found.".FormatWith(CultureInfo.InvariantCulture, FieldsPropertyName)); - PropertyInfo[] fieldProperties = (PropertyInfo[])FSharpUtils.GetUnionCaseInfoFields(matchingCaseInfo); - - if (fieldProperties.Length != fields.Count) - throw JsonSerializationException.Create(reader, "The number of field values does not match the number of properties definied by union '{0}'.".FormatWith(CultureInfo.InvariantCulture, caseName)); - - object[] typedFieldValues = new object[fieldProperties.Length]; - for (int i = 0; i < fields.Count; i++) + if (fields != null) { - JToken t = fields[i]; - PropertyInfo fieldProperty = fieldProperties[i]; + if (fieldProperties.Length != fields.Count) + throw JsonSerializationException.Create(reader, "The number of field values does not match the number of properties definied by union '{0}'.".FormatWith(CultureInfo.InvariantCulture, caseName)); - typedFieldValues[i] = t.ToObject(fieldProperty.PropertyType); + + for (int i = 0; i < fields.Count; i++) + { + JToken t = fields[i]; + PropertyInfo fieldProperty = fieldProperties[i]; + + typedFieldValues[i] = t.ToObject(fieldProperty.PropertyType); + } } return FSharpUtils.MakeUnion(null, matchingCaseInfo, typedFieldValues, null);