private void GenerateISerializableContract(Type type, JsonISerializableContract contract)
 {
     CurrentSchema.AllowAdditionalProperties = true;
 }
        private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            if (!JsonTypeReflector.FullyTrusted)
            {
                throw JsonSerializationException.Create(null, writer.ContainerPath, @"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data.
To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
            }

            OnSerializing(writer, contract, value);
            _serializeStack.Add(value);

            WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty);

            SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter());
            value.GetObjectData(serializationInfo, Serializer._context);

            foreach (SerializationEntry serializationEntry in serializationInfo)
            {
                JsonContract valueContract = GetContractSafe(serializationEntry.Value);

                if (CheckForCircularReference(writer, serializationEntry.Value, null, valueContract, contract, member))
                {
                    writer.WritePropertyName(serializationEntry.Name);
                    SerializeValue(writer, serializationEntry.Value, valueContract, null, contract, member);
                }
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);
            OnSerialized(writer, contract, value);
        }
        private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, string id)
        {
            Type objectType = contract.UnderlyingType;

            if (!JsonTypeReflector.FullyTrusted)
            {
                string message = @"Type '{0}' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data." + Environment.NewLine +
                                 @"To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true." + Environment.NewLine;
                message = message.FormatWith(CultureInfo.InvariantCulture, objectType);

                throw JsonSerializationException.Create(reader, message);
            }

            if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
                TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using ISerializable constructor.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null);

            SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter());

            bool finished = false;
            do
            {
                switch (reader.TokenType)
                {
                    case JsonToken.PropertyName:
                        string memberName = reader.Value.ToString();
                        if (!reader.Read())
                            throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

                        if (reader.TokenType == JsonToken.StartObject)
                        {
                            // this will read any potential type names embedded in json
                            object o = CreateObject(reader, null, null, null, contract, member, null);
                            serializationInfo.AddValue(memberName, o);
                        }
                        else
                        {
                            serializationInfo.AddValue(memberName, JToken.ReadFrom(reader));
                        }
                        break;
                    case JsonToken.Comment:
                        break;
                    case JsonToken.EndObject:
                        finished = true;
                        break;
                    default:
                        throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
                }
            } while (!finished && reader.Read());

            if (!finished)
                ThrowUnexpectedEndException(reader, contract, serializationInfo, "Unexpected end when deserializing object.");

            if (contract.ISerializableCreator == null)
                throw JsonSerializationException.Create(reader, "ISerializable type '{0}' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present.".FormatWith(CultureInfo.InvariantCulture, objectType));

            object createdObject = contract.ISerializableCreator(serializationInfo, Serializer._context);

            if (id != null)
                AddReference(reader, id, createdObject);

            // these are together because OnDeserializing takes an object but for an ISerializable the object is fully created in the constructor
            OnDeserializing(reader, contract, createdObject);
            OnDeserialized(reader, contract, createdObject);

            return createdObject;
        }