title: Serializing json object with its private properties deeply
body: <p>I want to serialize specific private fields that belongs to unmodifiable library class, how can i do that?</p>
  
  <p>To serialize private fields, I know that I can modify settings to serialize all private fields, but I do not want to serialize all fields. Just the specific fields.</p>
  
  <p>Also to serialize private fields, I know that JsonProperty or DataMember attribiutes can be written on the private fields. But I can not do that, because I can not modify library classes. Even if I can modify it, the library depends on an external library after modifying the library class (For example it depends on Newtonsoft.Json.dll if JsonProperty attribute is used).</p>
  
  <p>So I tried to create a custom attribute to solve it.  </p>
  
  <pre><code>// The class to serialize
  public class FeatureRepository
  {
      // Serialize all private properties that belongs to this object.
      public IDGenerator FeatureIDs;  
  
      // Do not serialize any private property that belongs to this object!
      public IDGenerator oldFeatureIDs;  
  }
  
  
  // Unmodifiable library class. Also it must be independent from any external libraries.
  // There are some private fields but they do not seem.
  public class IDGenerator
  {
      public IDGenerator();
  
      public uint GenerateID();
      public bool IsIDUsed(uint id);
      public void ReleaseID(uint id);
      public void UseID(uint id);
  }
  
  
  
  // Custom contract resolver
  public class MyContractResolver : DefaultContractResolver
  {
      // Target properties
      private List&lt;SerializableJson&gt; serializableJsons = new List&lt;SerializableJson&gt;();
  
      protected override JsonObjectContract CreateObjectContract(Type objectType)
      {
          JsonObjectContract contract = base.CreateObjectContract(objectType);
  
  
          // Detect SerializableJsonAttribute and store the property info
          foreach (JsonProperty property in contract.Properties)
          {
              IList&lt;Attribute&gt; attributes = property.AttributeProvider.GetAttributes(typeof(SerializableJsonAttribute), false);
  
              foreach (SerializableJsonAttribute temp in attributes)
              {
                  if (temp != null)
                  {
                      SerializableJson serializableJson = new SerializableJson()
                      {
                          PropertyType = property.PropertyType,
                          PropertyName = property.PropertyName
                      };
  
                      serializableJsons.Add(serializableJson);
                  }
              }
          }
  
          return contract;
      }
  
      protected override List&lt;MemberInfo&gt; GetSerializableMembers(Type objectType)
      {
          List&lt;MemberInfo&gt; members = base.GetSerializableMembers(objectType);
  
          // It can compare just the type, can not compare the property name here.
          SerializableJson serializableJson = serializableJsons.Where(temp =&gt; temp.PropertyType == objectType).FirstOrDefault();  
  
          // If the type is target type, add also private fields.
          if (serializableJson != null)
          {
              IEnumerable&lt;MemberInfo&gt; nonPublicMembers = GetFieldsAndProperties(objectType, BindingFlags.NonPublic)
                  .Where(m =&gt; m is PropertyInfo p ? !IsIndexedProperty(p) : true);
  
              foreach (MemberInfo member in nonPublicMembers)
                  members.Add(member);
          }
  
          return members;
      }
  }
  
  
  [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = false)]
  public class SerializableJsonAttribute : Attribute
  {
  
  }
  
  public class SerializableJson
  {
      public Type PropertyType { get; set; }
      public string PropertyName { get; set; }
  }
  
  
  
  // Finally use the custom attribute SerializableJson
  // Both of them will serialized with theirs private fields. 
  public class FeatureRepository
  {
      [SerializableJson]
      public IDGenerator FeatureIDs;  // I want to serialize all private properties that belongs to this object.
  
      public IDGenerator oldFeatureIDs;  // I do not want to serialize any private property that belongs to this object!
  }
  </code></pre>
  
  <p>How can I solve it?
  Or is there any different way to solve this problem than the way I have tried?               </p>
  
  <blockquote>
    <p>Blockquote</p>
  </blockquote>
  
  <p><strong>Edit</strong>  Let me explain the problem step by step: Firstly, FeatureRepository is serialized, SerializableJsonAttribute is searched for all properties. It finds the attribute on the FeatureIDs property but oldFeatureIDs. So it stores property type "IDGenerator" and property name "FeatureIDs". Secondly it starts to serialize IDGenerator. While serializing IDGenerator, you can not know that the serialization is done for "FeatureIDs" property or "oldFeatureIDs" property. If you would know, you can add private fields for "FeatureIDs" property.</p>