From a97ee01e7070a0c8505a5d72a5aaa27b890ec57e Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Sun, 26 May 2013 00:36:58 -0700 Subject: [PATCH 1/2] Added JsonIgnore Attribute When JsonIgnore is applied to a field or property, that member is ignored when deserializing and/or serializing. You can specify JsonIgnoreWhen.Serializing to only ignore serialization, *.Deserializing to only ignore deserializing, or default which is to ignore the field either way. Added unit tests for JsonIgnore, mroe to come. Updated Makefile. Updated .gitignore to include debug and OSX files. --- .gitignore | 4 + bin/LitJson.dll | Bin 52736 -> 54272 bytes build/make/Makefile | 9 +- src/LitJson/JsonAttribute.cs | 23 +++++ src/LitJson/JsonMapper.cs | 51 +++++++++- test/JsonIgnoreTest.cs | 175 +++++++++++++++++++++++++++++++++++ 6 files changed, 255 insertions(+), 7 deletions(-) create mode 100644 src/LitJson/JsonAttribute.cs create mode 100644 test/JsonIgnoreTest.cs diff --git a/.gitignore b/.gitignore index 6db94aa..ee9e58c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ /src/LitJson/AssemblyInfo.cs /website +*.sublime-project +*.sublime-workspace +*.mdb +.DS_Store diff --git a/bin/LitJson.dll b/bin/LitJson.dll index 03d340193bac68003dd46e46cc8da7cfd1e0cf45..af8234e7aa2cc352cdb656cf7502de50fd45e4f2 100755 GIT binary patch literal 54272 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 diff --git a/build/make/Makefile b/build/make/Makefile index f4fbdc0..cb3264f 100644 --- a/build/make/Makefile +++ b/build/make/Makefile @@ -34,7 +34,8 @@ SRC_FILES = \ $(srcdir)/JsonReader.cs \ $(srcdir)/JsonWriter.cs \ $(srcdir)/Lexer.cs \ - $(srcdir)/ParserToken.cs + $(srcdir)/ParserToken.cs \ + $(srcdir)/JsonAttribute.cs CLEAN_FILES += $(LITJSON_ASSEMBLY) $(GEN_FILES) $(LITJSON_MDB_FILE) @@ -43,6 +44,7 @@ CLEAN_FILES += $(LITJSON_ASSEMBLY) $(GEN_FILES) $(LITJSON_MDB_FILE) ## Tests ## TEST_ASSEMBLY = $(topdir)/bin/LitJson.Tests.dll +TEST_MDB_FILE = $(TEST_ASSEMBLY).mdb TEST_MONO_NUNIT = $(shell pkg-config --libs mono-nunit) @@ -51,9 +53,10 @@ TEST_SRC_FILES = \ $(testdir)/JsonDataTest.cs \ $(testdir)/JsonMapperTest.cs \ $(testdir)/JsonReaderTest.cs \ - $(testdir)/JsonWriterTest.cs + $(testdir)/JsonWriterTest.cs \ + $(testdir)/JsonIgnoreTest.cs -CLEAN_FILES += $(TEST_ASSEMBLY) $(builddir)/TestResult.xml +CLEAN_FILES += $(TEST_ASSEMBLY) $(TEST_MDB_FILE) $(builddir)/TestResult.xml ## diff --git a/src/LitJson/JsonAttribute.cs b/src/LitJson/JsonAttribute.cs new file mode 100644 index 0000000..aeddf37 --- /dev/null +++ b/src/LitJson/JsonAttribute.cs @@ -0,0 +1,23 @@ +using System; + +namespace LitJson +{ + [Flags] + public enum JsonIgnoreWhen + { + Never = 0, + Serializing = 1, + Deserializing = 2 + } + + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public class JsonIgnore : Attribute + { + public JsonIgnoreWhen Usage { get; private set; } + + public JsonIgnore(JsonIgnoreWhen usage = JsonIgnoreWhen.Serializing | JsonIgnoreWhen.Deserializing) + { + Usage = usage; + } + } +} diff --git a/src/LitJson/JsonMapper.cs b/src/LitJson/JsonMapper.cs index 4c1a036..a710067 100644 --- a/src/LitJson/JsonMapper.cs +++ b/src/LitJson/JsonMapper.cs @@ -21,9 +21,10 @@ namespace LitJson { internal struct PropertyMetadata { - public MemberInfo Info; - public bool IsField; - public Type Type; + public MemberInfo Info; + public bool IsField; + public Type Type; + public JsonIgnoreWhen Ignore; } @@ -224,6 +225,8 @@ private static void AddObjectMetadata (Type type) p_data.Info = p_info; p_data.Type = p_info.PropertyType; + ProcessAttributes(ref p_data, p_info); + data.Properties.Add (p_info.Name, p_data); } @@ -233,6 +236,8 @@ private static void AddObjectMetadata (Type type) p_data.IsField = true; p_data.Type = f_info.FieldType; + ProcessAttributes(ref p_data, f_info); + data.Properties.Add (f_info.Name, p_data); } @@ -259,6 +264,9 @@ private static void AddTypeProperties (Type type) PropertyMetadata p_data = new PropertyMetadata (); p_data.Info = p_info; p_data.IsField = false; + + ProcessAttributes(ref p_data, p_info); + props.Add (p_data); } @@ -267,6 +275,8 @@ private static void AddTypeProperties (Type type) p_data.Info = f_info; p_data.IsField = true; + ProcessAttributes(ref p_data, f_info); + props.Add (p_data); } @@ -279,6 +289,17 @@ private static void AddTypeProperties (Type type) } } + private static void ProcessAttributes (ref PropertyMetadata p_data, MemberInfo m_info) + { + foreach (Attribute attr in m_info.GetCustomAttributes(true)) { + if (attr is JsonIgnore) { + JsonIgnore ignore_attr = (JsonIgnore)attr; + p_data.Ignore = ignore_attr.Usage; + + } + } + } + private static MethodInfo GetConvOp (Type t1, Type t2) { lock (conv_ops_lock) { @@ -429,6 +450,12 @@ private static object ReadValue (Type inst_type, JsonReader reader) PropertyMetadata prop_data = t_data.Properties[property]; + // Don't deserialize a field or property that has a JsonIgnore attribute with deserialization usage. + if ((prop_data.Ignore & JsonIgnoreWhen.Deserializing) > 0) { + ReadSkip (reader); + continue; + } + if (prop_data.IsField) { ((FieldInfo) prop_data.Info).SetValue ( instance, ReadValue (prop_data.Type, reader)); @@ -633,12 +660,24 @@ private static void RegisterBaseImporters () RegisterImporter (base_importers_table, typeof (int), typeof (uint), importer); + importer = delegate (object input) { + return Convert.ToInt64 ((int) input); + }; + RegisterImporter (base_importers_table, typeof (int), + typeof (long), importer); + importer = delegate (object input) { return Convert.ToSingle ((int) input); }; RegisterImporter (base_importers_table, typeof (int), typeof (float), importer); + importer = delegate (object input) { + return Convert.ToSingle ((double) input); + }; + RegisterImporter (base_importers_table, typeof (double), + typeof (float), importer); + importer = delegate (object input) { return Convert.ToDouble ((int) input); }; @@ -651,7 +690,6 @@ private static void RegisterBaseImporters () RegisterImporter (base_importers_table, typeof (double), typeof (decimal), importer); - importer = delegate (object input) { return Convert.ToUInt32 ((long) input); }; @@ -801,6 +839,11 @@ private static void WriteValue (object obj, JsonWriter writer, writer.WriteObjectStart (); foreach (PropertyMetadata p_data in props) { + + // Don't serialize a field or property with the JsonIgnore attribute with serialization usage + if ((p_data.Ignore & JsonIgnoreWhen.Serializing) > 0) + continue; + if (p_data.IsField) { writer.WritePropertyName (p_data.Info.Name); WriteValue (((FieldInfo) p_data.Info).GetValue (obj), diff --git a/test/JsonIgnoreTest.cs b/test/JsonIgnoreTest.cs new file mode 100644 index 0000000..acded98 --- /dev/null +++ b/test/JsonIgnoreTest.cs @@ -0,0 +1,175 @@ +using LitJson; +using NUnit.Framework; +using System.Collections; + +namespace LitJson.Test +{ + class PrimitiveIgnoreFields + { + [JsonIgnore] public sbyte sbyteField; + [JsonIgnore] public byte byteField; + [JsonIgnore] public short shortField; + [JsonIgnore] public ushort ushortField; + [JsonIgnore] public int intField; + [JsonIgnore] public uint uintField; + [JsonIgnore] public long longField; + [JsonIgnore] public ulong ulongField; + [JsonIgnore] public decimal decimalField; + [JsonIgnore] public double doubleField; + [JsonIgnore] public float floatField; + [JsonIgnore] public string stringField; + [JsonIgnore] public bool boolField; + } + + class PrimitiveIgnoreProperties + { + [JsonIgnore] public sbyte sbyteField { get; set; } + [JsonIgnore] public byte byteField { get; set; } + [JsonIgnore] public short shortField { get; set; } + [JsonIgnore] public ushort ushortField { get; set; } + [JsonIgnore] public int intField { get; set; } + [JsonIgnore] public uint uintField { get; set; } + [JsonIgnore] public long longField { get; set; } + [JsonIgnore] public ulong ulongField { get; set; } + [JsonIgnore] public decimal decimalField { get; set; } + [JsonIgnore] public double doubleField { get; set; } + [JsonIgnore] public float floatField { get; set; } + [JsonIgnore] public string stringField { get; set; } + [JsonIgnore] public bool boolField { get; set; } + } + + class ObjectIgnoreFields + { + [JsonIgnore] public IDictionary dictField; + [JsonIgnore] public IList listField; + [JsonIgnore] public ObjectClass objectField; + } + + class ObjectIgnoreProperties + { + [JsonIgnore] public IDictionary dictField { get; set; } + [JsonIgnore] public IList listField { get; set; } + [JsonIgnore] public ObjectClass objectField { get; set; } + } + + class ObjectClass + { + public int ignored; + } + + [TestFixture] + public class JsonIgnoreTest + { + [Test] + public void CanIgnorePrimitiveFields() + { + string json = @"{ + ""sbyteField"": -1, + ""byteField"": 1, + ""shortField"": -1, + ""ushortField"": 1, + ""intField"": -1, + ""uintField"": 1, + ""longField"": -1, + ""ulongField"": 1, + ""decimalField"": 1.0, + ""doubleField"": 1.0, + ""floatField"": 1.0, + ""stringField"": ""value"", + ""boolField"": true + }"; + + PrimitiveIgnoreFields p_test = JsonMapper.ToObject(json); + + Assert.AreNotEqual((sbyte)-1, p_test.sbyteField); + Assert.AreNotEqual((byte)1, p_test.byteField); + Assert.AreNotEqual((short)-1, p_test.shortField); + Assert.AreNotEqual((ushort)1, p_test.ushortField); + Assert.AreNotEqual(-1, p_test.intField); + Assert.AreNotEqual(1, p_test.uintField); + Assert.AreNotEqual(-1L, p_test.longField); + Assert.AreNotEqual(1L, p_test.ulongField); + Assert.AreNotEqual(1.0M, p_test.decimalField); + Assert.AreNotEqual(1.0D, p_test.doubleField); + Assert.AreNotEqual(1.0F, p_test.floatField); + Assert.AreNotEqual("value", p_test.stringField); + Assert.AreNotEqual(true, p_test.boolField); + } + + [Test] + public void CanIgnorePrimitiveProperties() + { + string json = @"{ + ""sbyteField"": -1, + ""byteField"": 1, + ""shortField"": -1, + ""ushortField"": 1, + ""intField"": -1, + ""uintField"": 1, + ""longField"": -1, + ""ulongField"": 1, + ""decimalField"": 1.0, + ""doubleField"": 1.0, + ""floatField"": 1.0, + ""stringField"": ""value"", + ""boolField"": true + }"; + + PrimitiveIgnoreProperties p_test = JsonMapper.ToObject(json); + + Assert.AreNotEqual((sbyte)-1, p_test.sbyteField); + Assert.AreNotEqual((byte)1, p_test.byteField); + Assert.AreNotEqual((short)-1, p_test.shortField); + Assert.AreNotEqual((ushort)1, p_test.ushortField); + Assert.AreNotEqual(-1, p_test.intField); + Assert.AreNotEqual(1, p_test.uintField); + Assert.AreNotEqual(-1L, p_test.longField); + Assert.AreNotEqual(1L, p_test.ulongField); + Assert.AreNotEqual(1.0M, p_test.decimalField); + Assert.AreNotEqual(1.0D, p_test.doubleField); + Assert.AreNotEqual(1.0F, p_test.floatField); + Assert.AreNotEqual("value", p_test.stringField); + Assert.AreNotEqual(true, p_test.boolField); + } + + [Test] + public void CanIgnoreObjectFields() + { + string json = @"{ + ""dictField"": { + ""key"": ""value"" + }, + ""listField"": [1, 2, 3], + ""objectField"": { + ""ignored"": true + } + }"; + + ObjectIgnoreFields o_test = JsonMapper.ToObject(json); + + Assert.AreEqual(null, o_test.dictField); + Assert.AreEqual(null, o_test.listField); + Assert.AreEqual(null, o_test.objectField); + } + + [Test] + public void CanIgnoreObjectProperties() + { + string json = @"{ + ""dictField"": { + ""key"": ""value"" + }, + ""listField"": [1, 2, 3], + ""objectField"": { + ""ignored"": true + } + }"; + + ObjectIgnoreProperties o_test = JsonMapper.ToObject(json); + + Assert.AreEqual(null, o_test.dictField); + Assert.AreEqual(null, o_test.listField); + Assert.AreEqual(null, o_test.objectField); + } + } +} From 4d86f71ace7e7485136220e4d3553b5e67208ae4 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Sun, 26 May 2013 18:58:09 -0700 Subject: [PATCH 2/2] Finished unit testing for JsonIgnoreAttribute. Added float to the base exporter table. --- bin/LitJson.dll | Bin 54272 -> 54272 bytes src/LitJson/JsonMapper.cs | 5 + test/JsonIgnoreTest.cs | 561 +++++++++++++++++++++++++++++++++++++- 3 files changed, 557 insertions(+), 9 deletions(-) diff --git a/bin/LitJson.dll b/bin/LitJson.dll index af8234e7aa2cc352cdb656cf7502de50fd45e4f2..7ad65717883cfd609ed9b2fb23f52e41ec2b7869 100755 GIT binary patch delta 18005 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 delta 17854 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

lqD z|0P@aiwF_W?g9-zZbOPjX_4RHYT1sPG1nS?nsss8G%fOs*m}Vh-UYFx)ly%jYL4KI zByY51s)<^A&u<9Nf~`_tII(Xwo-YZ{ z$iBiTc-*{~Ei5I`KkEy`8-sHo6=P146Z6JMeZ3 zZ*Z};4ij4g7<*0-wuH*WHdELN!h02b8iX~|#mWNS=)}}h>j}^0U@_Qs(0cl@;xIP| zyDP>NRr~^UJN**OqS9zP3fkx%S|JQyw1C}9D^)XW9}C+-%_t zu6)~s=JBoo&`pfZ8e@UTlSDtw6=PLzQFQ|TxeA%-G__ik>c+7J>@Ka9< z@E;!jDS*8*W4fD5rF6apxFhpZWID~;6~8vj^sctqNwZWy&iD3qC@S$*0IQ%^)K3ta z7*szKvfVqx;i0fEAA`Tj_X^|Ex4Y<4XWtjO*M zxmIwL;55NSf-42r3*IjHpx`dS{etfbek%A4V~jfHaEl5AD}Zey_m*oy^YjA71%g)# zUMqN`;3OAYrwR5ZmJ0;C32uUqhi)x+*QMy5f=_@?6!1{KAb7BV2O@SvE`Kff0_Kw< zTm5Y4EVwJ@6!di56m!ggpwZz0#oM7DRveQGiW!Z*&JcNC zF;}*GrVu$|J<)lH=zxzp8V z!8---6KoZHTJQzI{lNTmbx6n&!4CyL7yP>PQ(eu9s1iLoE4LUXZ7Z4x<6#%Y{HF9};ivm;9m{CG$&Pw2 z2jh=LCRKxDxyfEsuUSuMS0`A|*XZDZ_zL54_gGdXSkSj- zoCB|#O(PdvYciwYx`gdD>rVQQ1Pl5$I&Mg?dfy$6^~vS*=?il&`laKiNgj_lZb|lV zY)aT(vp(h6oM1uU?j%<4`<=dbVRo!Gr`CBZRr0%FOt=ek&Ig-(~TG3T`Nm(*ag zH)5#%9_lmLFn%Iz^ALk+xlY$T^peRca!XwIQ|iTR+l0A2+4T@zonUia57Tuf+ih)d zJwi_>Sd*)jP9@mm_D8Am5+llPYpmJz7!6C%b*{&0X@YHVJwaPdHa7PY=aaNE!8W^| zqJ1WtoV(TaG+BomLABh+UC+=6lQrblI(JdM$(n`D5w?Lg<{pT-c2R>#@6MeI)@-uf zV0&nz$=(KgmUf!#?_kf<(i%yyBO|Z8qb)?bmFToB|z+{~ZUU$7iA(Qni zIN*Ah>P$9B*f5ig7B)s0--I4|mtr##^t9{G)F5mXj8^v%{1TQc^knfp@*X*bt#MBA zd+9yOGT9=3mF+zWnyeYN_bFtu+hBX2hMDXs*pAT{ll>94V>BgZ(jzb)r#UA3o3I9x zo%W}?kJD0>qitwuzL5$ zG)|b2!%t|2VRPP8xP(5T`IqyH1FYY76dnRyXBr`t;xQnZabVPt&OcJMB76Q)aTK zF{0nl9AU;?@eMVYjPHtX=xUSkUGXh7n~d*@Z>hy#F(=P_QX5U#Xv^ zM!E4|>1u|_rh;XtFHANUEK`LR8=ecnyy}$6mX*XFbo-RE(J)3~%u-uS_7kvd^@+)D z1j|tanheidz;e}MlidcErye%hcCdVvwv;_r(E}x3Do_JV_E^ahu*JgG(5@1140N0v z#a7Y25(UP^;-|7Wz}efZwEOa&9X*;2HQQMM?UDZz0_K0mKb!}BYYPG~#a`1MMbfBVb zBHttOqayDT`Gq9e(4^y?uSVHG3l#&ccqHTqWt~}H zb`(pfk~GN`zo1Wztkyq?jLR6|Z||+q1iyas3U8n+z_phHEmQ$ibiSZp!nYLa>#xqs z#seJ;SwM|)L@pO|AAR?V^I~_3#%NrJ6!tXmE56C%6dy@7t>pbAws} zd>69P_(7f9ja6Ce;)ry%ex)i9?qaEaFw9l@+p9;;yeZ{kdQKgs4YWgzv2CCwUB=k< z(j#gO?G^oA`a+F|=3{k;ocMRG)k&$e7MMmYzzo^|%%V-eJh~Mapsm0X+79fluGLpx zccEnqu79{L*D^rcrGI!`IM$+ZoSQX{vr*$Xw^%n=D`>XkD|ZDgaM)8SsL7EFj0moF z6hhWTzSS`g@?^(Jc;4WsNV%KtcKjse0?Th4Ypt^_&p9@wthU?_`EJ4I1drNSqwI`@ z_WSWDXdNtMrr;{UI|cU&9u-s$DIhplaHilY!8--_3LX_yPVpBUEI3nemEfI%dx5dF z)}um{O9}|?&0zUhUMsM|^cM*w@>2d$(WMFLq9L{@8h^^GWAR&M%!7R}a?=SHyL{>p54zUFKfk z{*ilyyV-rC`%!(v+8(hHSgPyXjF$*rCOA=WhTxTg`#Z7ENkL!Q6v*eL%>+(LWBt0c zxxj}-ep}Gyxe}VLf}=f)AUAoqR7j#FYQ$f9(YdPp*DH7_gB$Uopfi)@GQq)uQw1Y} z$=%>)#p3NU`tXL2Uq$n506_fjGs5xmY@3yl%^ zW-m8UG%@;2$Z78^n6C}6;by@df=>!QC-}!ePwb^exQB|kp}#3&{~5MT(EnEC85UhTn<#!L;VbLcfktvb7(5ntQaum*8rn{Rn5H0|>X^#(SKnp>Zn| z$XP$>%G)g4EDu>82ky4)v;4vGs^x^`OUr3XcWaaFd7PYf&;j6mbQpL)odE8nFMtma zEhl=AQh^Uq7Vu#z0se|AfsfDtU@Hv+K1$<&kLmBMpEzYj7u?ra@yUN)<>^_IVACB3Udvumn*hkDHH)vKyUpUU3V zJ!Z|B*Sp7gGiQfpombtfa#pWit-Cg-d0OAyu}IT*KhU9d;?5r_=eY3bSy#=Sy;MK` zK$q6M2Ya|$hdpsJRj+$~nA)pf|NQUO-qvw1)Yx%Z|A)@XL!nJA)rEIe*FAG`(!R%L Vr4+S#Uj3WW>r{Gc$Nit%{s*$8(json); + + Assert.AreEqual((sbyte)-1, p_test.sbyteField); + Assert.AreEqual((byte)1, p_test.byteField); + Assert.AreEqual((short)-1, p_test.shortField); + Assert.AreEqual((ushort)1, p_test.ushortField); + Assert.AreEqual(-1, p_test.intField); + Assert.AreEqual(1, p_test.uintField); + Assert.AreEqual(-1L, p_test.longField); + Assert.AreEqual(1L, p_test.ulongField); + Assert.AreEqual(1.0M, p_test.decimalField); + Assert.AreEqual(1.0D, p_test.doubleField); + Assert.AreEqual(1.0F, p_test.floatField); + Assert.AreEqual("value", p_test.stringField); + Assert.AreEqual(true, p_test.boolField); + } + + [Test] + public void CanIgnorePrimitivePropertiesOnlyWhenSerializing() + { + PrimitiveIgnorePropertiesSerializing p_test = new PrimitiveIgnorePropertiesSerializing { + sbyteField = -1, + byteField = 1, + shortField = -1, + ushortField = 1, + intField = -1, + uintField = 1, + longField = -1, + ulongField = 1, + decimalField = 1.0M, + doubleField = 1.0D, + floatField = 1.0F, + stringField = "value", + boolField = true + }; + + string json = JsonMapper.ToJson(p_test); + + Assert.AreEqual("{}", json); + + json = @"{ + ""sbyteField"": -1, + ""byteField"": 1, + ""shortField"": -1, + ""ushortField"": 1, + ""intField"": -1, + ""uintField"": 1, + ""longField"": -1, + ""ulongField"": 1, + ""decimalField"": 1.0, + ""doubleField"": 1.0, + ""floatField"": 1.0, + ""stringField"": ""value"", + ""boolField"": true + }"; + + p_test = JsonMapper.ToObject(json); + + Assert.AreEqual((sbyte)-1, p_test.sbyteField); + Assert.AreEqual((byte)1, p_test.byteField); + Assert.AreEqual((short)-1, p_test.shortField); + Assert.AreEqual((ushort)1, p_test.ushortField); + Assert.AreEqual(-1, p_test.intField); + Assert.AreEqual(1, p_test.uintField); + Assert.AreEqual(-1L, p_test.longField); + Assert.AreEqual(1L, p_test.ulongField); + Assert.AreEqual(1.0M, p_test.decimalField); + Assert.AreEqual(1.0D, p_test.doubleField); + Assert.AreEqual(1.0F, p_test.floatField); + Assert.AreEqual("value", p_test.stringField); + Assert.AreEqual(true, p_test.boolField); + } + + [Test] + public void CanIgnoreObjectFieldsOnlyWhenSerializing() + { + ObjectIgnoreFieldsSerializing o_test = new ObjectIgnoreFieldsSerializing { + dictField = new Hashtable(), + listField = new ArrayList(), + objectField = new ObjectClass() + }; + + string json = JsonMapper.ToJson(o_test); + + Assert.AreEqual("{}", json); + + json = @"{ + ""dictField"": { + ""key"": ""value"" + }, + ""listField"": [1, 2, 3], + ""objectField"": { + ""ignored"": true + } + }"; + + o_test = JsonMapper.ToObject(json); + + Assert.AreNotEqual(null, o_test.dictField); + Assert.AreNotEqual(null, o_test.listField); + Assert.AreNotEqual(null, o_test.objectField); + + Assert.AreEqual(1, o_test.dictField.Count); + Assert.AreEqual("value", (string)(JsonData)o_test.dictField["key"]); + + Assert.AreEqual(3, o_test.listField.Count); + Assert.AreEqual(1, o_test.listField[0]); + Assert.AreEqual(2, o_test.listField[1]); + Assert.AreEqual(3, o_test.listField[2]); + + Assert.AreEqual(true, o_test.objectField.ignored); + } + + [Test] + public void CanIgnoreObjectPropertiesOnlyWhenSerializing() + { + ObjectIgnorePropertiesSerializing o_test = new ObjectIgnorePropertiesSerializing { + dictField = new Hashtable(), + listField = new ArrayList(), + objectField = new ObjectClass() + }; + + string json = JsonMapper.ToJson(o_test); + + Assert.AreEqual("{}", json); + + json = @"{ + ""dictField"": { + ""key"": ""value"" + }, + ""listField"": [1, 2, 3], + ""objectField"": { + ""ignored"": true + } + }"; + + o_test = JsonMapper.ToObject(json); + + Assert.AreNotEqual(null, o_test.dictField); + Assert.AreNotEqual(null, o_test.listField); + Assert.AreNotEqual(null, o_test.objectField); + + Assert.AreEqual(1, o_test.dictField.Count); + Assert.AreEqual("value", (string)(JsonData)o_test.dictField["key"]); + + Assert.AreEqual(3, o_test.listField.Count); + Assert.AreEqual(1, o_test.listField[0]); + Assert.AreEqual(2, o_test.listField[1]); + Assert.AreEqual(3, o_test.listField[2]); + + Assert.AreEqual(true, o_test.objectField.ignored); + } + + [Test] + public void CanIgnorePrimitiveFieldsOnlyWhenDeserializing() + { + string json = @"{ + ""sbyteField"": -1, + ""byteField"": 1, + ""shortField"": -1, + ""ushortField"": 1, + ""intField"": -1, + ""uintField"": 1, + ""longField"": -1, + ""ulongField"": 1, + ""decimalField"": 1.0, + ""doubleField"": 1.0, + ""floatField"": 1.0, + ""stringField"": ""value"", + ""boolField"": true + }"; + + PrimitiveIgnoreFieldsDeserializing p_test = JsonMapper.ToObject(json); + + Assert.AreNotEqual((sbyte)-1, p_test.sbyteField); + Assert.AreNotEqual((byte)1, p_test.byteField); + Assert.AreNotEqual((short)-1, p_test.shortField); + Assert.AreNotEqual((ushort)1, p_test.ushortField); + Assert.AreNotEqual(-1, p_test.intField); + Assert.AreNotEqual(1, p_test.uintField); + Assert.AreNotEqual(-1L, p_test.longField); + Assert.AreNotEqual(1L, p_test.ulongField); + Assert.AreNotEqual(1.0M, p_test.decimalField); + Assert.AreNotEqual(1.0D, p_test.doubleField); + Assert.AreNotEqual(1.0F, p_test.floatField); + Assert.AreNotEqual("value", p_test.stringField); + Assert.AreNotEqual(true, p_test.boolField); + + p_test = new PrimitiveIgnoreFieldsDeserializing { + sbyteField = -1, + byteField = 1, + shortField = -1, + ushortField = 1, + intField = -1, + uintField = 1, + longField = -1, + ulongField = 1, + decimalField = 1.0M, + doubleField = 1.0D, + floatField = 1.0F, + stringField = "value", + boolField = true + }; + + string json2 = JsonMapper.ToJson(p_test); + + Assert.AreEqual(Regex.Replace(json, @"\s+", ""), json2); + } + + [Test] + public void CanIgnorePrimitivePropertiesOnlyWhenDeserializing() + { + string json = @"{ + ""sbyteField"": -1, + ""byteField"": 1, + ""shortField"": -1, + ""ushortField"": 1, + ""intField"": -1, + ""uintField"": 1, + ""longField"": -1, + ""ulongField"": 1, + ""decimalField"": 1.0, + ""doubleField"": 1.0, + ""floatField"": 1.0, + ""stringField"": ""value"", + ""boolField"": true + }"; + + PrimitiveIgnorePropertiesDeserializing p_test = JsonMapper.ToObject(json); + + Assert.AreNotEqual((sbyte)-1, p_test.sbyteField); + Assert.AreNotEqual((byte)1, p_test.byteField); + Assert.AreNotEqual((short)-1, p_test.shortField); + Assert.AreNotEqual((ushort)1, p_test.ushortField); + Assert.AreNotEqual(-1, p_test.intField); + Assert.AreNotEqual(1, p_test.uintField); + Assert.AreNotEqual(-1L, p_test.longField); + Assert.AreNotEqual(1L, p_test.ulongField); + Assert.AreNotEqual(1.0M, p_test.decimalField); + Assert.AreNotEqual(1.0D, p_test.doubleField); + Assert.AreNotEqual(1.0F, p_test.floatField); + Assert.AreNotEqual("value", p_test.stringField); + Assert.AreNotEqual(true, p_test.boolField); + + p_test = new PrimitiveIgnorePropertiesDeserializing { + sbyteField = -1, + byteField = 1, + shortField = -1, + ushortField = 1, + intField = -1, + uintField = 1, + longField = -1, + ulongField = 1, + decimalField = 1.0M, + doubleField = 1.0D, + floatField = 1.0F, + stringField = "value", + boolField = true + }; + + string json2 = JsonMapper.ToJson(p_test); + + Assert.AreEqual(Regex.Replace(json, @"\s+", ""), json2); + } + + [Test] + public void CanIgnoreObjectFieldsOnlyWhenDeserializing() + { + string json = @"{ + ""dictField"": { + ""key"": ""value"" + }, + ""listField"": [1, 2, 3], + ""objectField"": { + ""ignored"": true + } + }"; + + ObjectIgnoreFieldsDeserializing o_test = JsonMapper.ToObject(json); + + Assert.AreEqual(null, o_test.dictField); + Assert.AreEqual(null, o_test.listField); + Assert.AreEqual(null, o_test.objectField); + + o_test = new ObjectIgnoreFieldsDeserializing { + dictField = new Hashtable { + {"key", "value"} + }, + listField = new ArrayList(new int[]{1, 2, 3}), + objectField = new ObjectClass { + ignored = true + } + }; + + string json2 = JsonMapper.ToJson(o_test); + Assert.AreEqual(Regex.Replace(json, @"\s+", ""), json2); + } + + [Test] + public void CanIgnoreObjectPropertiesOnlyWhenDeserializing() + { + string json = @"{ + ""dictField"": { + ""key"": ""value"" + }, + ""listField"": [1, 2, 3], + ""objectField"": { + ""ignored"": true + } + }"; + + ObjectIgnorePropertiesDeserializing o_test = JsonMapper.ToObject(json); + + Assert.AreEqual(null, o_test.dictField); + Assert.AreEqual(null, o_test.listField); + Assert.AreEqual(null, o_test.objectField); + + o_test = new ObjectIgnorePropertiesDeserializing { + dictField = new Hashtable { + {"key", "value"} + }, + listField = new ArrayList(new int[]{1, 2, 3}), + objectField = new ObjectClass { + ignored = true + } + }; + + string json2 = JsonMapper.ToJson(o_test); + Assert.AreEqual(Regex.Replace(json, @"\s+", ""), json2); + } } }