Просмотр исходного кода

Added Json(ExplicitMembersOnly=true) attribute

Brad Robinson 2 лет назад
Родитель
Сommit
6b2293abac

+ 70 - 0
Topten.JsonKit.Test/TestExplicitMembersOnly.cs

@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Topten.JsonKit;
+using System.IO;
+using System.Reflection;
+using Xunit;
+
+namespace TestCases
+{
+    [Obfuscation(Exclude = true, ApplyToMembers = true)]
+    public class TestExplicitMembersOnly
+    {
+        class Thing
+        {
+            public string Apples = "apples";
+        }
+
+        [Json(ExplicitMembersOnly = true)]
+        class Thing2
+        {
+            public string Apples = "apples";
+        }
+
+        [Json(ExplicitMembersOnly = true)]
+        class Thing3
+        {
+            [Json("apples")]
+            public string Apples = "apples";
+        }
+
+        [Fact]
+        public void TestNonDecoratedClass()
+        {
+            var thing = new Thing();
+
+            // Save it
+            var json = Json.Format(thing);
+
+            // Check the object kinds were written out
+            Assert.Contains("\"apples\":", json);
+        }
+
+        [Fact]
+        public void TestDecoratedEmptyClass()
+        {
+            var thing = new Thing2();
+
+            // Save it
+            var json = Json.Format(thing);
+
+            // Check the object kinds were written out
+            Assert.DoesNotContain("\"apples\":", json);
+        }
+
+        [Fact]
+        public void TestDecoratedNonEmptyClass()
+        {
+            var thing = new Thing3();
+
+            // Save it
+            var json = Json.Format(thing);
+
+            // Check the object kinds were written out
+            Assert.Contains("\"apples\":", json);
+        }
+
+    }
+}

+ 10 - 0
Topten.JsonKit/JsonAttribute.cs

@@ -126,5 +126,15 @@ namespace Topten.JsonKit
             set;
         }
 
+        /// <summary>
+        /// If no members are marked with JSON attributes, don't try to serialize
+        /// the whole type - instead serialize as an empty object.
+        /// </summary>
+        public bool ExplicitMembersOnly
+        {
+            get;
+            set;
+        }
+
     }
 }

+ 13 - 1
Topten.JsonKit/ReflectionInfo.cs

@@ -184,11 +184,21 @@ namespace Topten.JsonKit
                 var allMembers = Utils.GetAllFieldsAndProperties(type); 
 
                 // Does type have a [Json] attribute
-                bool typeMarked = type.GetCustomAttributes(typeof(JsonAttribute), true).OfType<JsonAttribute>().Any();
+                var typeAttr = type.GetCustomAttributes(typeof(JsonAttribute), true).OfType<JsonAttribute>().FirstOrDefault();
+                bool typeMarked = typeAttr != null;
 
                 // Do any members have a [Json] attribute
                 bool anyFieldsMarked = allMembers.Any(x => x.GetCustomAttributes(typeof(JsonAttribute), false).OfType<JsonAttribute>().Any());
 
+                // If the type is marked with [Json(ExplicitFieldsOnly = true)] then ignore the type attribute
+                // and only serialize fields explicitly marked.
+                if (typeAttr != null && typeAttr.ExplicitMembersOnly)
+                {
+                    anyFieldsMarked = true;
+                    typeAttr = null;
+                    typeMarked = false;
+                }
+
                 // Try with DataContract and friends
                 if (!typeMarked && !anyFieldsMarked && type.GetCustomAttributes(typeof(DataContractAttribute), true).OfType<DataContractAttribute>().Any())
                 {
@@ -265,8 +275,10 @@ namespace Topten.JsonKit
             }
 
             // Must have some members
+            /*
             if (!members.Any() && !Attribute.IsDefined(type, typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false))
                 return null;
+            */
 
             // Create reflection info
             return new ReflectionInfo() { Members = members };