I\'m using Json.NET in my WCF data service.
Here\'s my class (simplified):
[DataContract]
public class Component
{
public Component()
{
The best option to avoid constructor calls on deserialization is to create special contract resolver that overrides creator function for all classes without constructor marked with JsonConstructor attribute. This way you still can force JSON.NET to call constructor if you really need it, but all other classes will be created much like in standard DataContract serializers in .NET. Here is the code:
///
/// Special contract resolver to create objects bypassing constructor call.
///
public class NoConstructorCreationContractResolver : DefaultContractResolver
{
///
/// Creates a for the given type.
///
/// Type of the object.
///
/// A for the given type.
///
protected override JsonObjectContract CreateObjectContract(Type objectType)
{
// prepare contract using default resolver
var objectContract = base.CreateObjectContract(objectType);
// if type has constructor marked with JsonConstructor attribute or can't be instantiated, return default contract
if (objectContract.OverrideConstructor != null || objectContract.CreatedType.IsInterface || objectContract.CreatedType.IsAbstract)
return objectContract;
// prepare function to check that specified constructor parameter corresponds to non writable property on a type
Func isParameterForNonWritableProperty =
parameter =>
{
var propertyForParameter = objectContract.Properties.FirstOrDefault(property => property.PropertyName == parameter.PropertyName);
if (propertyForParameter == null)
return false;
return !propertyForParameter.Writable;
};
// if type has parameterized constructor and any of constructor parameters corresponds to non writable property, return default contract
// this is needed to handle special cases for types that can be initialized only via constructor, i.e. Tuple<>
if (objectContract.ParametrizedConstructor != null
&& objectContract.ConstructorParameters.Any(parameter => isParameterForNonWritableProperty(parameter)))
return objectContract;
// override default creation method to create object without constructor call
objectContract.DefaultCreatorNonPublic = false;
objectContract.DefaultCreator = () => FormatterServices.GetSafeUninitializedObject(objectContract.CreatedType);
return objectContract;
}
}
All you need is simply set this contract resolver in serializer settings before deserialization.