-Added support for BindToName on SerializationBinder
This commit is contained in:
@@ -125,10 +125,13 @@
|
||||
<Compile Include="Schema\JsonSchemaNodeTests.cs" />
|
||||
<Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
|
||||
<Compile Include="Serialization\ConstructorHandlingTests.cs" />
|
||||
<Compile Include="Serialization\ContractResolverTests.cs" />
|
||||
<Compile Include="Serialization\DefaultValueHandlingTests.cs" />
|
||||
<Compile Include="Serialization\DynamicTests.cs" />
|
||||
<Compile Include="Serialization\EntitiesSerializationTests.cs" />
|
||||
<Compile Include="Serialization\JsonSerializerTest.cs" />
|
||||
<Compile Include="Serialization\MissingMemberHandlingTests.cs" />
|
||||
<Compile Include="Serialization\NullValueHandlingTests.cs" />
|
||||
<Compile Include="Serialization\PopulateTests.cs" />
|
||||
<Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
|
||||
<Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
|
||||
|
||||
@@ -88,9 +88,13 @@
|
||||
<Compile Include="Schema\JsonSchemaNodeTests.cs" />
|
||||
<Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
|
||||
<Compile Include="Serialization\ConstructorHandlingTests.cs" />
|
||||
<Compile Include="Serialization\ContractResolverTests.cs" />
|
||||
<Compile Include="Serialization\DefaultValueHandlingTests.cs" />
|
||||
<Compile Include="Serialization\DynamicTests.cs" />
|
||||
<Compile Include="Serialization\EntitiesSerializationTests.cs" />
|
||||
<Compile Include="Serialization\JsonSerializerTest.cs" />
|
||||
<Compile Include="Serialization\MissingMemberHandlingTests.cs" />
|
||||
<Compile Include="Serialization\NullValueHandlingTests.cs" />
|
||||
<Compile Include="Serialization\PopulateTests.cs" />
|
||||
<Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
|
||||
<Compile Include="Serialization\SerializationErrorHandlingTests.cs" />
|
||||
|
||||
@@ -41,5 +41,5 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.0.2.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.0.2.13904")]
|
||||
[assembly: AssemblyFileVersion("4.0.2.13928")]
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#if !(NET35 || NET20)
|
||||
#if !(NET35 || NET20 || WINDOWS_PHONE)
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -4511,5 +4511,98 @@ keyword such as type of business.""
|
||||
Assert.AreEqual(1, c2.Categories["one"]);
|
||||
Assert.AreEqual(2, c2.Categories["two"]);
|
||||
}
|
||||
|
||||
[JsonObject(MemberSerialization.OptIn)]
|
||||
public class ClassAttributeBase
|
||||
{
|
||||
[JsonProperty]
|
||||
public string BaseClassValue { get; set; }
|
||||
}
|
||||
|
||||
public class ClassAttributeDerived : ClassAttributeBase
|
||||
{
|
||||
[JsonProperty]
|
||||
public string DerivedClassValue { get; set; }
|
||||
|
||||
public string NonSerialized { get; set; }
|
||||
}
|
||||
|
||||
public class CollectionClassAttributeDerived : ClassAttributeBase, ICollection<object>
|
||||
{
|
||||
[JsonProperty]
|
||||
public string CollectionDerivedClassValue { get; set; }
|
||||
|
||||
public void Add(object item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Contains(object item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CopyTo(object[] array, int arrayIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public bool Remove(object item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IEnumerator<object> GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ClassAttributesInheritance()
|
||||
{
|
||||
string json = JsonConvert.SerializeObject(new ClassAttributeDerived
|
||||
{
|
||||
BaseClassValue = "BaseClassValue!",
|
||||
DerivedClassValue = "DerivedClassValue!",
|
||||
NonSerialized = "NonSerialized!"
|
||||
}, Formatting.Indented);
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""DerivedClassValue"": ""DerivedClassValue!"",
|
||||
""BaseClassValue"": ""BaseClassValue!""
|
||||
}", json);
|
||||
|
||||
json = JsonConvert.SerializeObject(new CollectionClassAttributeDerived
|
||||
{
|
||||
BaseClassValue = "BaseClassValue!",
|
||||
CollectionDerivedClassValue = "CollectionDerivedClassValue!"
|
||||
}, Formatting.Indented);
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""CollectionDerivedClassValue"": ""CollectionDerivedClassValue!"",
|
||||
""BaseClassValue"": ""BaseClassValue!""
|
||||
}", json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -430,7 +430,6 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual(5, nested[4]);
|
||||
}
|
||||
|
||||
#if !SILVERLIGHT && !PocketPC
|
||||
[Test]
|
||||
public void DeserializeUsingCustomBinder()
|
||||
{
|
||||
@@ -460,6 +459,89 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
return typeof (Person);
|
||||
}
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35)
|
||||
[Test]
|
||||
public void SerializeUsingCustomBinder()
|
||||
{
|
||||
IList<object> values = new List<object>
|
||||
{
|
||||
new Person
|
||||
{
|
||||
BirthDate = new DateTime(2000, 10, 23, 1, 1, 1, DateTimeKind.Utc),
|
||||
LastModified = new DateTime(2000, 10, 23, 1, 1, 1, DateTimeKind.Utc),
|
||||
Name = "Name!",
|
||||
Department = "Department!"
|
||||
},
|
||||
new Employee
|
||||
{
|
||||
BirthDate = new DateTime(2000, 10, 23, 1, 1, 1, DateTimeKind.Utc),
|
||||
FirstName = "FirstName!",
|
||||
LastName = "LastName!",
|
||||
Department = "Department!",
|
||||
JobTitle = "JobTitle!"
|
||||
}
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
Binder = new CompleteSerializationBinder()
|
||||
});
|
||||
|
||||
Assert.AreEqual(@"[
|
||||
{
|
||||
""$type"": ""Person"",
|
||||
""Name"": ""Name!"",
|
||||
""BirthDate"": ""\/Date(972262861000)\/"",
|
||||
""LastModified"": ""\/Date(972262861000)\/""
|
||||
},
|
||||
{
|
||||
""$type"": ""Employee"",
|
||||
""FirstName"": ""FirstName!"",
|
||||
""LastName"": ""LastName!"",
|
||||
""BirthDate"": ""\/Date(972262861000)\/"",
|
||||
""Department"": ""Department!"",
|
||||
""JobTitle"": ""JobTitle!""
|
||||
}
|
||||
]", json);
|
||||
|
||||
IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
Binder = new CompleteSerializationBinder()
|
||||
});
|
||||
|
||||
Assert.IsInstanceOfType(typeof(Person), newValues[0]);
|
||||
Person person = (Person)newValues[0];
|
||||
Assert.AreEqual("Name!", person.Name);
|
||||
|
||||
Assert.IsInstanceOfType(typeof(Employee), newValues[1]);
|
||||
Employee employee = (Employee)newValues[1];
|
||||
Assert.AreEqual("FirstName!", employee.FirstName);
|
||||
}
|
||||
|
||||
public class CompleteSerializationBinder : SerializationBinder
|
||||
{
|
||||
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
|
||||
{
|
||||
assemblyName = null;
|
||||
typeName = serializedType.Name;
|
||||
}
|
||||
|
||||
public override Type BindToType(string assemblyName, string typeName)
|
||||
{
|
||||
switch (typeName)
|
||||
{
|
||||
case "Employee":
|
||||
return typeof (Employee);
|
||||
case "Person":
|
||||
return typeof (Person);
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -110,7 +110,7 @@ using System.Security;
|
||||
// by using the '*' as shown below:
|
||||
[assembly: AssemblyVersion("4.0.2.0")]
|
||||
#if !PocketPC
|
||||
[assembly: AssemblyFileVersion("4.0.2.13904")]
|
||||
[assembly: AssemblyFileVersion("4.0.2.13928")]
|
||||
#endif
|
||||
|
||||
[assembly: CLSCompliant(true)]
|
||||
|
||||
@@ -116,5 +116,18 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
return _typeCache.Get(new TypeNameKey(assemblyName, typeName));
|
||||
}
|
||||
|
||||
#if !(NET35 || NET20)
|
||||
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
|
||||
{
|
||||
#if !SILVERLIGHT
|
||||
assemblyName = serializedType.Assembly.FullName;
|
||||
typeName = serializedType.FullName;
|
||||
#else
|
||||
assemblyName = null;
|
||||
typeName = serializedType.AssemblyQualifiedName;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -357,7 +357,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
private void WriteTypeProperty(JsonWriter writer, Type type)
|
||||
{
|
||||
writer.WritePropertyName(JsonTypeReflector.TypePropertyName);
|
||||
writer.WriteValue(ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat));
|
||||
writer.WriteValue(ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat, Serializer.Binder));
|
||||
}
|
||||
|
||||
private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag)
|
||||
|
||||
@@ -16,6 +16,12 @@ namespace Newtonsoft.Json
|
||||
/// <param name="typeName">Specifies the <see cref="Type"/> name of the serialized object</param>
|
||||
/// <returns></returns>
|
||||
public abstract Type BindToType(string assemblyName, string typeName);
|
||||
|
||||
public virtual void BindToName(Type serializedType, out string assemblyName, out string typeName)
|
||||
{
|
||||
assemblyName = null;
|
||||
typeName = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -29,6 +29,7 @@ using System.Reflection;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -59,10 +60,31 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat)
|
||||
{
|
||||
return GetTypeName(t, assemblyFormat, null);
|
||||
}
|
||||
|
||||
public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder)
|
||||
{
|
||||
string fullyQualifiedTypeName;
|
||||
#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)
|
||||
{
|
||||
case FormatterAssemblyStyle.Simple:
|
||||
return GetSimpleTypeName(t);
|
||||
return RemoveAssemblyDetails(fullyQualifiedTypeName);
|
||||
case FormatterAssemblyStyle.Full:
|
||||
return t.AssemblyQualifiedName;
|
||||
default:
|
||||
@@ -70,19 +92,8 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetSimpleTypeName(Type type)
|
||||
private static string RemoveAssemblyDetails(string fullyQualifiedTypeName)
|
||||
{
|
||||
#if !SILVERLIGHT
|
||||
string fullyQualifiedTypeName = type.FullName + ", " + type.Assembly.GetName().Name;
|
||||
|
||||
// for type names with no nested type names then return
|
||||
if (!type.IsGenericType || type.IsGenericTypeDefinition)
|
||||
return fullyQualifiedTypeName;
|
||||
#else
|
||||
// Assembly.GetName() is marked SecurityCritical
|
||||
string fullyQualifiedTypeName = type.AssemblyQualifiedName;
|
||||
#endif
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
// loop through the type name and filter out qualified assembly details from nested type names
|
||||
|
||||
Reference in New Issue
Block a user