I have a webservice with a method that takes a parameter of abstract base type Specification<TDomainModel>
as parameter. I realize that WCF don't know how to de-/serialize this without specifying known types. But when I try to specify them, I still get this exception:
There was an error while trying to serialize parameter http://myproject.org:specification. The InnerException message was 'Type 'MyProject.DomainModel.WebSnapshot.WebSnapshotSpecification' with data contract name 'WebSnapshotSpecification:http://schemas.datacontract.org/2004/07/MyProject.DomainModel.WebSnapshot' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
If anyone can see where I have missed something, it would be very much appreciated :) The classes looks as follows:
WebSnapshotRepositoryService
:
[ServiceContract(Namespace = "http://myproject.org")]
[ServiceKnownType(typeof(Specification<WebSnapshot>))]
[ServiceKnownType(typeof(WebSnapshotSpecification))]
public class WebSnapshotRepositoryService
{
[OperationContract]
public IEnumerable<WebSnapshot> Get(Specification<WebSnapshot> specification)
{
// Code here.
}
}
and WebSnapshotSpecification
:
public class WebSnapshotSpecification : Specification<WebSnapshot>
{
public override Expression<Func<WebSnapshot, bool>> IsSatisfiedByExpression()
{
return (t) => true;
}
}
which is a specification of WebSnapshot
:
[DataContract(IsReference = true, Name = "WebSnapshot", Namespace = "MyProject.DomainModel.WebSnapshot")]
public class WebSnapshot
{
[DataMember(Order = 1)]
public virtual string Name { get; set; }
[DataMember(Order = 2)]
public virtual string PictureFilePath { get; set; }
[DataMember(Order = 3)]
public virtual int PictureHeight { get; set; }
[DataMember(Order = 4)]
public virtual int PictureWidth { get; set; }
}
finally, here is Specification<TDomainModel>
:
public abstract class Specification<TDomainModel>
{
public virtual bool IsSatisfiedBy(TDomainModel domainObject)
{
return IsSatisfiedByExpression().Compile().Invoke(domainObject);
}
public virtual TDomainModel AssembleObject()
{
return Activator.CreateInstance<TDomainModel>();
}
public abstract Expression<Func<TDomainModel, bool>> IsSatisfiedByExpression();
}