-Added ISerializationBinder

-Added SerializationBinder properties to JsonSerializer and JsonSerializerSettings
-Changed Binder properties on JsonSerializer and JsonSerializerSettings to obsolete
This commit is contained in:
James Newton-King
2016-09-16 16:10:13 +12:00
parent a0403492ad
commit 4f8a22594f
19 changed files with 358 additions and 39 deletions
@@ -1631,7 +1631,9 @@ namespace Newtonsoft.Json.Tests.Bson
var settings = new JsonSerializerSettings var settings = new JsonSerializerSettings
{ {
TypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto,
#pragma warning disable CS0618 // Type or member is obsolete
Binder = binder Binder = binder
#pragma warning restore CS0618 // Type or member is obsolete
}; };
Zoo zoo = new Zoo Zoo zoo = new Zoo
@@ -23,10 +23,9 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
#endregion #endregion
#if !(NET20 || NET35)
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json.Serialization;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Text; using System.Text;
#if DNXCORE50 #if DNXCORE50
@@ -49,16 +48,16 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer
public class SerializeSerializationBinder : TestFixtureBase public class SerializeSerializationBinder : TestFixtureBase
{ {
#region Types #region Types
public class KnownTypesBinder : SerializationBinder public class KnownTypesBinder : ISerializationBinder
{ {
public IList<Type> KnownTypes { get; set; } public IList<Type> KnownTypes { get; set; }
public override Type BindToType(string assemblyName, string typeName) public Type BindToType(string assemblyName, string typeName)
{ {
return KnownTypes.SingleOrDefault(t => t.Name == typeName); return KnownTypes.SingleOrDefault(t => t.Name == typeName);
} }
public override void BindToName(Type serializedType, out string assemblyName, out string typeName) public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{ {
assemblyName = null; assemblyName = null;
typeName = serializedType.Name; typeName = serializedType.Name;
@@ -90,7 +89,7 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer
string json = JsonConvert.SerializeObject(car, Formatting.Indented, new JsonSerializerSettings string json = JsonConvert.SerializeObject(car, Formatting.Indented, new JsonSerializerSettings
{ {
TypeNameHandling = TypeNameHandling.Objects, TypeNameHandling = TypeNameHandling.Objects,
Binder = knownTypesBinder SerializationBinder = knownTypesBinder
}); });
Console.WriteLine(json); Console.WriteLine(json);
@@ -103,7 +102,7 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer
object newValue = JsonConvert.DeserializeObject(json, new JsonSerializerSettings object newValue = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
{ {
TypeNameHandling = TypeNameHandling.Objects, TypeNameHandling = TypeNameHandling.Objects,
Binder = knownTypesBinder SerializationBinder = knownTypesBinder
}); });
Console.WriteLine(newValue.GetType().Name); Console.WriteLine(newValue.GetType().Name);
@@ -114,5 +113,3 @@ namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer
} }
} }
} }
#endif
@@ -1178,8 +1178,23 @@ namespace Newtonsoft.Json.Tests.Serialization
JsonSerializer serializer = new JsonSerializer(); JsonSerializer serializer = new JsonSerializer();
DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
#pragma warning disable CS0618 // Type or member is obsolete
serializer.Binder = customBinder; serializer.Binder = customBinder;
Assert.AreEqual(customBinder, serializer.Binder); Assert.AreEqual(customBinder, serializer.Binder);
#pragma warning restore CS0618 // Type or member is obsolete
Assert.IsInstanceOf(typeof(SerializationBinderAdapter), serializer.SerializationBinder);
serializer.SerializationBinder = customBinder;
Assert.AreEqual(customBinder, serializer.SerializationBinder);
ExceptionAssert.Throws<InvalidOperationException>(() =>
{
#pragma warning disable CS0618 // Type or member is obsolete
var serializationBinder = serializer.Binder;
#pragma warning restore CS0618 // Type or member is obsolete
serializationBinder.ToString();
}, "Cannot get SerializationBinder because an ISerializationBinder was previously set.");
serializer.CheckAdditionalContent = true; serializer.CheckAdditionalContent = true;
Assert.AreEqual(true, serializer.CheckAdditionalContent); Assert.AreEqual(true, serializer.CheckAdditionalContent);
@@ -1273,8 +1288,10 @@ namespace Newtonsoft.Json.Tests.Serialization
JsonSerializerSettings settings = new JsonSerializerSettings(); JsonSerializerSettings settings = new JsonSerializerSettings();
DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
#pragma warning disable CS0618 // Type or member is obsolete
settings.Binder = customBinder; settings.Binder = customBinder;
Assert.AreEqual(customBinder, settings.Binder); Assert.AreEqual(customBinder, settings.Binder);
#pragma warning restore CS0618 // Type or member is obsolete
settings.CheckAdditionalContent = true; settings.CheckAdditionalContent = true;
Assert.AreEqual(true, settings.CheckAdditionalContent); Assert.AreEqual(true, settings.CheckAdditionalContent);
@@ -1374,8 +1391,23 @@ namespace Newtonsoft.Json.Tests.Serialization
JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer())); JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer()));
DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
#pragma warning disable CS0618 // Type or member is obsolete
serializerProxy.Binder = customBinder; serializerProxy.Binder = customBinder;
Assert.AreEqual(customBinder, serializerProxy.Binder); Assert.AreEqual(customBinder, serializerProxy.Binder);
#pragma warning restore CS0618 // Type or member is obsolete
Assert.IsInstanceOf(typeof(SerializationBinderAdapter), serializerProxy.SerializationBinder);
serializerProxy.SerializationBinder = customBinder;
Assert.AreEqual(customBinder, serializerProxy.SerializationBinder);
ExceptionAssert.Throws<InvalidOperationException>(() =>
{
#pragma warning disable CS0618 // Type or member is obsolete
var serializationBinder = serializerProxy.Binder;
#pragma warning restore CS0618 // Type or member is obsolete
serializationBinder.ToString();
}, "Cannot get SerializationBinder because an ISerializationBinder was previously set.");
serializerProxy.CheckAdditionalContent = true; serializerProxy.CheckAdditionalContent = true;
Assert.AreEqual(true, serializerProxy.CheckAdditionalContent); Assert.AreEqual(true, serializerProxy.CheckAdditionalContent);
@@ -731,7 +731,9 @@ namespace Newtonsoft.Json.Tests.Serialization
object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
{ {
TypeNameHandling = TypeNameHandling.Objects, TypeNameHandling = TypeNameHandling.Objects,
#pragma warning disable CS0618 // Type or member is obsolete
Binder = new CustomSerializationBinder() Binder = new CustomSerializationBinder()
#pragma warning restore CS0618 // Type or member is obsolete
}); });
CustomAssert.IsInstanceOfType(typeof(Person), p); CustomAssert.IsInstanceOfType(typeof(Person), p);
@@ -772,7 +774,9 @@ namespace Newtonsoft.Json.Tests.Serialization
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
{ {
TypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto,
#pragma warning disable CS0618 // Type or member is obsolete
Binder = binder Binder = binder
#pragma warning restore CS0618 // Type or member is obsolete
}); });
//[ //[
@@ -804,7 +808,9 @@ namespace Newtonsoft.Json.Tests.Serialization
IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
{ {
TypeNameHandling = TypeNameHandling.Auto, TypeNameHandling = TypeNameHandling.Auto,
#pragma warning disable CS0618 // Type or member is obsolete
Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests") Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
#pragma warning restore CS0618 // Type or member is obsolete
}); });
CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]); CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]);
@@ -840,6 +846,95 @@ namespace Newtonsoft.Json.Tests.Serialization
} }
#endif #endif
[Test]
public void NewSerializeUsingCustomBinder()
{
NewTypeNameSerializationBinder binder = new NewTypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
IList<object> values = new List<object>
{
new Customer
{
Name = "Caroline Customer"
},
new Purchase
{
ProductName = "Elbow Grease",
Price = 5.99m,
Quantity = 1
}
};
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
SerializationBinder = binder
});
//[
// {
// "$type": "Customer",
// "Name": "Caroline Customer"
// },
// {
// "$type": "Purchase",
// "ProductName": "Elbow Grease",
// "Price": 5.99,
// "Quantity": 1
// }
//]
StringAssert.AreEqual(@"[
{
""$type"": ""Customer"",
""Name"": ""Caroline Customer""
},
{
""$type"": ""Purchase"",
""ProductName"": ""Elbow Grease"",
""Price"": 5.99,
""Quantity"": 1
}
]", json);
IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
SerializationBinder = new NewTypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
});
CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]);
Customer customer = (Customer)newValues[0];
Assert.AreEqual("Caroline Customer", customer.Name);
CustomAssert.IsInstanceOfType(typeof(Purchase), newValues[1]);
Purchase purchase = (Purchase)newValues[1];
Assert.AreEqual("Elbow Grease", purchase.ProductName);
}
public class NewTypeNameSerializationBinder : ISerializationBinder
{
public string TypeFormat { get; private set; }
public NewTypeNameSerializationBinder(string typeFormat)
{
TypeFormat = typeFormat;
}
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
assemblyName = null;
typeName = serializedType.Name;
}
public Type BindToType(string assemblyName, string typeName)
{
string resolvedTypeName = string.Format(TypeFormat, typeName);
return Type.GetType(resolvedTypeName, true);
}
}
[Test] [Test]
public void CollectionWithAbstractItems() public void CollectionWithAbstractItems()
{ {
@@ -1193,7 +1288,9 @@ namespace Newtonsoft.Json.Tests.Serialization
{ {
TypeNameHandling = TypeNameHandling.All, TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
#pragma warning disable CS0618 // Type or member is obsolete
Binder = new MetroBinder(), Binder = new MetroBinder(),
#pragma warning restore CS0618 // Type or member is obsolete
ContractResolver = new DefaultContractResolver ContractResolver = new DefaultContractResolver
{ {
#if !(NETFX_CORE || PORTABLE || DNXCORE50) #if !(NETFX_CORE || PORTABLE || DNXCORE50)
+38 -6
View File
@@ -58,7 +58,7 @@ namespace Newtonsoft.Json
internal IContractResolver _contractResolver; internal IContractResolver _contractResolver;
internal ITraceWriter _traceWriter; internal ITraceWriter _traceWriter;
internal IEqualityComparer _equalityComparer; internal IEqualityComparer _equalityComparer;
internal SerializationBinder _binder; internal ISerializationBinder _serializationBinder;
internal StreamingContext _context; internal StreamingContext _context;
private IReferenceResolver _referenceResolver; private IReferenceResolver _referenceResolver;
@@ -101,9 +101,24 @@ namespace Newtonsoft.Json
/// <summary> /// <summary>
/// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names. /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
/// </summary> /// </summary>
[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
public virtual SerializationBinder Binder public virtual SerializationBinder Binder
{ {
get { return _binder; } get
{
if (_serializationBinder == null)
{
return null;
}
SerializationBinderAdapter adapter = _serializationBinder as SerializationBinderAdapter;
if (adapter != null)
{
return adapter.SerializationBinder;
}
throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
}
set set
{ {
if (value == null) if (value == null)
@@ -111,7 +126,24 @@ namespace Newtonsoft.Json
throw new ArgumentNullException(nameof(value), "Serialization binder cannot be null."); throw new ArgumentNullException(nameof(value), "Serialization binder cannot be null.");
} }
_binder = value; _serializationBinder = new SerializationBinderAdapter(value);
}
}
/// <summary>
/// Gets or sets the <see cref="ISerializationBinder"/> used by the serializer when resolving type names.
/// </summary>
public virtual ISerializationBinder SerializationBinder
{
get { return _serializationBinder; }
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value), "Serialization binder cannot be null.");
}
_serializationBinder = value;
} }
} }
@@ -488,7 +520,7 @@ namespace Newtonsoft.Json
_typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling; _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling;
_metadataPropertyHandling = JsonSerializerSettings.DefaultMetadataPropertyHandling; _metadataPropertyHandling = JsonSerializerSettings.DefaultMetadataPropertyHandling;
_context = JsonSerializerSettings.DefaultContext; _context = JsonSerializerSettings.DefaultContext;
_binder = DefaultSerializationBinder.Instance; _serializationBinder = DefaultSerializationBinder.Instance;
_culture = JsonSerializerSettings.DefaultCulture; _culture = JsonSerializerSettings.DefaultCulture;
_contractResolver = DefaultContractResolver.Instance; _contractResolver = DefaultContractResolver.Instance;
@@ -656,9 +688,9 @@ namespace Newtonsoft.Json
{ {
serializer.EqualityComparer = settings.EqualityComparer; serializer.EqualityComparer = settings.EqualityComparer;
} }
if (settings.Binder != null) if (settings.SerializationBinder != null)
{ {
serializer.Binder = settings.Binder; serializer.SerializationBinder = settings.SerializationBinder;
} }
// reader/writer specific // reader/writer specific
+26 -1
View File
@@ -251,7 +251,32 @@ namespace Newtonsoft.Json
/// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names. /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
/// </summary> /// </summary>
/// <value>The binder.</value> /// <value>The binder.</value>
public SerializationBinder Binder { get; set; } [Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
public SerializationBinder Binder
{
get
{
if (SerializationBinder == null)
{
return null;
}
SerializationBinderAdapter adapter = SerializationBinder as SerializationBinderAdapter;
if (adapter != null)
{
return adapter.SerializationBinder;
}
throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
}
set { SerializationBinder = value == null ? null : new SerializationBinderAdapter(value); }
}
/// <summary>
/// Gets or sets the <see cref="ISerializationBinder"/> used by the serializer when resolving type names.
/// </summary>
/// <value>The binder.</value>
public ISerializationBinder SerializationBinder { get; set; }
/// <summary> /// <summary>
/// Gets or sets the error handler called during serialization and deserialization. /// Gets or sets the error handler called during serialization and deserialization.
@@ -134,12 +134,14 @@
<Compile Include="Serialization\DiagnosticsTraceWriter.cs" /> <Compile Include="Serialization\DiagnosticsTraceWriter.cs" />
<Compile Include="Serialization\ExpressionValueProvider.cs" /> <Compile Include="Serialization\ExpressionValueProvider.cs" />
<Compile Include="Serialization\IAttributeProvider.cs" /> <Compile Include="Serialization\IAttributeProvider.cs" />
<Compile Include="Serialization\ISerializationBinder.cs" />
<Compile Include="Serialization\ITraceWriter.cs" /> <Compile Include="Serialization\ITraceWriter.cs" />
<Compile Include="Serialization\JsonContainerContract.cs" /> <Compile Include="Serialization\JsonContainerContract.cs" />
<Compile Include="Serialization\JsonDynamicContract.cs" /> <Compile Include="Serialization\JsonDynamicContract.cs" />
<Compile Include="Serialization\MemoryTraceWriter.cs" /> <Compile Include="Serialization\MemoryTraceWriter.cs" />
<Compile Include="Serialization\NamingStrategy.cs" /> <Compile Include="Serialization\NamingStrategy.cs" />
<Compile Include="Serialization\ReflectionAttributeProvider.cs" /> <Compile Include="Serialization\ReflectionAttributeProvider.cs" />
<Compile Include="Serialization\SerializationBinderAdapter.cs" />
<Compile Include="Serialization\SnakeCaseNamingStrategy.cs" /> <Compile Include="Serialization\SnakeCaseNamingStrategy.cs" />
<Compile Include="Serialization\TraceJsonReader.cs" /> <Compile Include="Serialization\TraceJsonReader.cs" />
<Compile Include="Serialization\TraceJsonWriter.cs" /> <Compile Include="Serialization\TraceJsonWriter.cs" />
@@ -148,11 +148,13 @@
<Compile Include="Serialization\DiagnosticsTraceWriter.cs" /> <Compile Include="Serialization\DiagnosticsTraceWriter.cs" />
<Compile Include="Serialization\ExpressionValueProvider.cs" /> <Compile Include="Serialization\ExpressionValueProvider.cs" />
<Compile Include="Serialization\IAttributeProvider.cs" /> <Compile Include="Serialization\IAttributeProvider.cs" />
<Compile Include="Serialization\ISerializationBinder.cs" />
<Compile Include="Serialization\ITraceWriter.cs" /> <Compile Include="Serialization\ITraceWriter.cs" />
<Compile Include="Serialization\JsonContainerContract.cs" /> <Compile Include="Serialization\JsonContainerContract.cs" />
<Compile Include="Serialization\MemoryTraceWriter.cs" /> <Compile Include="Serialization\MemoryTraceWriter.cs" />
<Compile Include="Serialization\NamingStrategy.cs" /> <Compile Include="Serialization\NamingStrategy.cs" />
<Compile Include="Serialization\ReflectionAttributeProvider.cs" /> <Compile Include="Serialization\ReflectionAttributeProvider.cs" />
<Compile Include="Serialization\SerializationBinderAdapter.cs" />
<Compile Include="Serialization\SnakeCaseNamingStrategy.cs" /> <Compile Include="Serialization\SnakeCaseNamingStrategy.cs" />
<Compile Include="Serialization\TraceJsonReader.cs" /> <Compile Include="Serialization\TraceJsonReader.cs" />
<Compile Include="Serialization\TraceJsonWriter.cs" /> <Compile Include="Serialization\TraceJsonWriter.cs" />
@@ -147,11 +147,13 @@
<Compile Include="Serialization\DiagnosticsTraceWriter.cs" /> <Compile Include="Serialization\DiagnosticsTraceWriter.cs" />
<Compile Include="Serialization\ExpressionValueProvider.cs" /> <Compile Include="Serialization\ExpressionValueProvider.cs" />
<Compile Include="Serialization\IAttributeProvider.cs" /> <Compile Include="Serialization\IAttributeProvider.cs" />
<Compile Include="Serialization\ISerializationBinder.cs" />
<Compile Include="Serialization\ITraceWriter.cs" /> <Compile Include="Serialization\ITraceWriter.cs" />
<Compile Include="Serialization\JsonContainerContract.cs" /> <Compile Include="Serialization\JsonContainerContract.cs" />
<Compile Include="Serialization\MemoryTraceWriter.cs" /> <Compile Include="Serialization\MemoryTraceWriter.cs" />
<Compile Include="Serialization\NamingStrategy.cs" /> <Compile Include="Serialization\NamingStrategy.cs" />
<Compile Include="Serialization\ReflectionAttributeProvider.cs" /> <Compile Include="Serialization\ReflectionAttributeProvider.cs" />
<Compile Include="Serialization\SerializationBinderAdapter.cs" />
<Compile Include="Serialization\SnakeCaseNamingStrategy.cs" /> <Compile Include="Serialization\SnakeCaseNamingStrategy.cs" />
<Compile Include="Serialization\TraceJsonReader.cs" /> <Compile Include="Serialization\TraceJsonReader.cs" />
<Compile Include="Serialization\TraceJsonWriter.cs" /> <Compile Include="Serialization\TraceJsonWriter.cs" />
@@ -179,6 +179,7 @@
<Compile Include="Serialization\IAttributeProvider.cs" /> <Compile Include="Serialization\IAttributeProvider.cs" />
<Compile Include="Serialization\IContractResolver.cs" /> <Compile Include="Serialization\IContractResolver.cs" />
<Compile Include="Serialization\IReferenceResolver.cs" /> <Compile Include="Serialization\IReferenceResolver.cs" />
<Compile Include="Serialization\ISerializationBinder.cs" />
<Compile Include="Serialization\ITraceWriter.cs" /> <Compile Include="Serialization\ITraceWriter.cs" />
<Compile Include="Serialization\IValueProvider.cs" /> <Compile Include="Serialization\IValueProvider.cs" />
<Compile Include="Serialization\JsonArrayContract.cs" /> <Compile Include="Serialization\JsonArrayContract.cs" />
@@ -205,6 +206,7 @@
<Compile Include="Serialization\OnErrorAttribute.cs" /> <Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Serialization\ReflectionAttributeProvider.cs" /> <Compile Include="Serialization\ReflectionAttributeProvider.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" /> <Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="Serialization\SerializationBinderAdapter.cs" />
<Compile Include="Serialization\SnakeCaseNamingStrategy.cs" /> <Compile Include="Serialization\SnakeCaseNamingStrategy.cs" />
<Compile Include="Serialization\TraceJsonReader.cs" /> <Compile Include="Serialization\TraceJsonReader.cs" />
<Compile Include="Serialization\TraceJsonWriter.cs" /> <Compile Include="Serialization\TraceJsonWriter.cs" />
@@ -184,6 +184,7 @@
<Compile Include="Serialization\IAttributeProvider.cs" /> <Compile Include="Serialization\IAttributeProvider.cs" />
<Compile Include="Serialization\IContractResolver.cs" /> <Compile Include="Serialization\IContractResolver.cs" />
<Compile Include="Serialization\IReferenceResolver.cs" /> <Compile Include="Serialization\IReferenceResolver.cs" />
<Compile Include="Serialization\ISerializationBinder.cs" />
<Compile Include="Serialization\ITraceWriter.cs" /> <Compile Include="Serialization\ITraceWriter.cs" />
<Compile Include="Serialization\IValueProvider.cs" /> <Compile Include="Serialization\IValueProvider.cs" />
<Compile Include="Serialization\JsonArrayContract.cs" /> <Compile Include="Serialization\JsonArrayContract.cs" />
@@ -210,6 +211,7 @@
<Compile Include="Serialization\OnErrorAttribute.cs" /> <Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Serialization\ReflectionAttributeProvider.cs" /> <Compile Include="Serialization\ReflectionAttributeProvider.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" /> <Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="Serialization\SerializationBinderAdapter.cs" />
<Compile Include="Serialization\SnakeCaseNamingStrategy.cs" /> <Compile Include="Serialization\SnakeCaseNamingStrategy.cs" />
<Compile Include="Serialization\TraceJsonReader.cs" /> <Compile Include="Serialization\TraceJsonReader.cs" />
<Compile Include="Serialization\TraceJsonWriter.cs" /> <Compile Include="Serialization\TraceJsonWriter.cs" />
@@ -169,6 +169,8 @@
<Compile Include="Schema\ValidationEventHandler.cs" /> <Compile Include="Schema\ValidationEventHandler.cs" />
<Compile Include="SerializationBinder.cs" /> <Compile Include="SerializationBinder.cs" />
<Compile Include="Serialization\CachedAttributeGetter.cs" /> <Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="Serialization\ISerializationBinder.cs" />
<Compile Include="Serialization\SerializationBinderAdapter.cs" />
<Compile Include="Serialization\SnakeCaseNamingStrategy.cs" /> <Compile Include="Serialization\SnakeCaseNamingStrategy.cs" />
<Compile Include="Serialization\CamelCaseNamingStrategy.cs" /> <Compile Include="Serialization\CamelCaseNamingStrategy.cs" />
<Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" /> <Compile Include="Serialization\CamelCasePropertyNamesContractResolver.cs" />
@@ -35,7 +35,7 @@ namespace Newtonsoft.Json.Serialization
/// <summary> /// <summary>
/// The default serialization binder used when resolving and loading classes from type names. /// The default serialization binder used when resolving and loading classes from type names.
/// </summary> /// </summary>
public class DefaultSerializationBinder : SerializationBinder public class DefaultSerializationBinder : SerializationBinder, ISerializationBinder
{ {
internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder(); internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder();
@@ -187,14 +187,17 @@ namespace Newtonsoft.Json.Serialization
return GetTypeByName(new TypeNameKey(assemblyName, typeName)); return GetTypeByName(new TypeNameKey(assemblyName, typeName));
} }
#if !(NET35 || NET20)
/// <summary> /// <summary>
/// When overridden in a derived class, controls the binding of a serialized object to a type. /// When overridden in a derived class, controls the binding of a serialized object to a type.
/// </summary> /// </summary>
/// <param name="serializedType">The type of the object the formatter creates a new instance of.</param> /// <param name="serializedType">The type of the object the formatter creates a new instance of.</param>
/// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object. </param> /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object. </param>
/// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object. </param> /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object. </param>
public override void BindToName(Type serializedType, out string assemblyName, out string typeName) public
#if !(NET35 || NET20)
override
#endif
void BindToName(Type serializedType, out string assemblyName, out string typeName)
{ {
#if (DOTNET || PORTABLE) #if (DOTNET || PORTABLE)
assemblyName = serializedType.GetTypeInfo().Assembly.FullName; assemblyName = serializedType.GetTypeInfo().Assembly.FullName;
@@ -204,6 +207,5 @@ namespace Newtonsoft.Json.Serialization
typeName = serializedType.FullName; typeName = serializedType.FullName;
#endif #endif
} }
#endif
} }
} }
@@ -0,0 +1,53 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Reflection;
using System.Runtime.Serialization;
namespace Newtonsoft.Json.Serialization
{
/// <summary>
/// Allows users to control class loading and mandate what class to load.
/// </summary>
public interface ISerializationBinder
{
/// <summary>
/// When implemented, controls the binding of a serialized object to a type.
/// </summary>
/// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
/// <param name="typeName">Specifies the <see cref="System.Type"/> name of the serialized object</param>
/// <returns>The type of the object the formatter creates a new instance of.</returns>
Type BindToType(string assemblyName, string typeName);
/// <summary>
/// When implemented, controls the binding of a serialized object to a type.
/// </summary>
/// <param name="serializedType">The type of the object the formatter creates a new instance of.</param>
/// <param name="assemblyName">Specifies the <see cref="Assembly"/> name of the serialized object.</param>
/// <param name="typeName">Specifies the <see cref="System.Type"/> name of the serialized object.</param>
void BindToName(Type serializedType, out string assemblyName, out string typeName);
}
}
@@ -783,7 +783,7 @@ namespace Newtonsoft.Json.Serialization
Type specifiedType; Type specifiedType;
try try
{ {
specifiedType = Serializer._binder.BindToType(typeNameKey.AssemblyName, typeNameKey.TypeName); specifiedType = Serializer._serializationBinder.BindToType(typeNameKey.AssemblyName, typeNameKey.TypeName);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -603,7 +603,7 @@ namespace Newtonsoft.Json.Serialization
private void WriteTypeProperty(JsonWriter writer, Type type) private void WriteTypeProperty(JsonWriter writer, Type type)
{ {
string typeName = ReflectionUtils.GetTypeName(type, Serializer._typeNameAssemblyFormat, Serializer._binder); string typeName = ReflectionUtils.GetTypeName(type, Serializer._typeNameAssemblyFormat, Serializer._serializationBinder);
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose)
{ {
@@ -133,12 +133,19 @@ namespace Newtonsoft.Json.Serialization
set { _serializer.ConstructorHandling = value; } set { _serializer.ConstructorHandling = value; }
} }
[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
public override SerializationBinder Binder public override SerializationBinder Binder
{ {
get { return _serializer.Binder; } get { return _serializer.Binder; }
set { _serializer.Binder = value; } set { _serializer.Binder = value; }
} }
public override ISerializationBinder SerializationBinder
{
get { return _serializer.SerializationBinder; }
set { _serializer.SerializationBinder = value; }
}
public override StreamingContext Context public override StreamingContext Context
{ {
get { return _serializer.Context; } get { return _serializer.Context; }
@@ -0,0 +1,55 @@
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Runtime.Serialization;
namespace Newtonsoft.Json.Serialization
{
internal class SerializationBinderAdapter : ISerializationBinder
{
public readonly SerializationBinder SerializationBinder;
public SerializationBinderAdapter(SerializationBinder serializationBinder)
{
SerializationBinder = serializationBinder;
}
public Type BindToType(string assemblyName, string typeName)
{
return SerializationBinder.BindToType(assemblyName, typeName);
}
public void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
#if !(NET35 || NET20)
SerializationBinder.BindToName(serializedType, out assemblyName, out typeName);
#else
assemblyName = null;
typeName = null;
#endif
}
}
}
@@ -151,23 +151,9 @@ namespace Newtonsoft.Json.Utilities
return (v != null) ? v.GetType() : null; return (v != null) ? v.GetType() : null;
} }
public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder) public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, ISerializationBinder binder)
{ {
string fullyQualifiedTypeName; string fullyQualifiedTypeName = GetFullyQualifiedTypeName(t, binder);
#if !(NET20 || NET35)
if (binder != null)
{
string assemblyName, typeName;
binder.BindToName(t, out assemblyName, out typeName);
fullyQualifiedTypeName = typeName + (assemblyName == null ? "" : ", " + assemblyName);
}
else
{
fullyQualifiedTypeName = t.AssemblyQualifiedName;
}
#else
fullyQualifiedTypeName = t.AssemblyQualifiedName;
#endif
switch (assemblyFormat) switch (assemblyFormat)
{ {
@@ -180,6 +166,25 @@ namespace Newtonsoft.Json.Utilities
} }
} }
private static string GetFullyQualifiedTypeName(Type t, ISerializationBinder binder)
{
if (binder != null)
{
string assemblyName, typeName;
binder.BindToName(t, out assemblyName, out typeName);
#if (NET20 || NET35)
// for older SerializationBinder implementations that didn't have BindToName
if (assemblyName == null & typeName == null)
{
return t.AssemblyQualifiedName;
}
#endif
return typeName + (assemblyName == null ? "" : ", " + assemblyName);
}
return t.AssemblyQualifiedName;
}
private static string RemoveAssemblyDetails(string fullyQualifiedTypeName) private static string RemoveAssemblyDetails(string fullyQualifiedTypeName)
{ {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();