JsonDynamicContract returning "only" dynamic properties

Apr 9, 2011 at 1:52 AM

I have an object that implements IDynamicMetaObjectProvider and, before anything, the DefaultContractResolver doesn't return a JsonDynamicContract, it returns a JsonObjectContract, i think the call to: 

t = ReflectionUtils.EnsureNotNullableType(objectType);
Is the responsable of that (the base class is ScrollableControl) but, anyway, if i implement a ContractResolver and return a JsonDynamicContract, onlye the dynamic properties of the object get serialized and  i have all my class decorated, the class with JsonObjectAttribute( OptIn ) and the propertys with JsonProperty, the problem here is that i need both kinds of variables serialized and the object is way to complex to write a JsonConverter for it.
Is there a way to do this with a semi-transparent method?
Apr 9, 2011 at 4:15 PM

Follow up:

Ok, so i ended up with two problems, on the first hand, the IDynamicMetaObjectProvider only gets its dynamic properties serialized, i solved that by modifying JsonSerializerInternalWriter, the SerializeDynamic method is now like this:

 

 private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract)
    {
      contract.InvokeOnSerializing(value, Serializer.Context);
      SerializeStack.Add(value);

      writer.WriteStartObject();
      int initialDepth = writer.Top;
        
      foreach ( JsonProperty property in contract.Properties )
      {
          try
          {
              if ( !property.Ignored && property.Readable && ShouldSerialize( property, value ) && IsSpecified( property, value ) )
              {
                  object memberValue = property.ValueProvider.GetValue( value );
                  JsonContract memberContract = GetContractSafe( memberValue );

                  WriteMemberInfoProperty( writer, memberValue, property, memberContract );
              }
          }
          catch ( Exception ex )
          {
              if ( IsErrorHandled( value, contract, property.PropertyName, ex ) )
                  HandleError( writer, initialDepth );
              else
                  throw;
          }
      }

      foreach (string memberName in value.GetDynamicMemberNames())
      {
        object memberValue;
        if (DynamicUtils.TryGetMember(value, memberName, out memberValue))
        {
          string resolvedPropertyName = (contract.PropertyNameResolver != null)
            ? contract.PropertyNameResolver(memberName)
            : memberName;
          
          writer.WritePropertyName(resolvedPropertyName);
          SerializeValue(writer, memberValue, GetContractSafe(memberValue), null, null);
        }
      }

      writer.WriteEndObject();

      SerializeStack.RemoveAt(SerializeStack.Count - 1);
      contract.InvokeOnSerialized(value, Serializer.Context);
    }
So it now serializes all my properties respecting the attributes set on the class. I must add that i also implemented a ContratResolver based on DefaultContractResolver and overrided CreateProperties so it dont use OptOut and still uses OptIn.
Before this i was trying to return all the needed properties in the dynamic properties collection but, that has an ugly side effect, it doesn't pay attention to any attributes set on the class so, personalized names on propertys or converters are not taken into acount, now everything is working as it should but... I want to use it in a standard way, i don't like to mess with others code, well, i like to but, in this particular case, the library is still active and i believe this is something that will be useful for many.