如何在WCF中使用没有属性“KnownType”的接口数据类型?

如果我正在使用包含“OperationContract”操作的“ServiceContract”。 操作返回或接收接口参数。 当我使用该服务时,我收到一条exception消息:

“反序列化器不知道映射到此名称的任何类型。如果使用DataContractSerializer或将与'{%className%}’对应的类型添加到已知类型列表中,请考虑使用DataContractResolver”。

我可以将KnowTypes的属性添加到接口,但我的接口项目与实现项目分离,并且它们不能具有循环依赖性引用,因此无法声明KnowTypes。

什么是最好的解决方案?

不幸的是,这是不可能的。 类似的问题已经被问到: 使用WCF接口

我找到了一个解决方案并且它有效!

我正在使用ServiceKnownType来加载为DataContract成员实现ServiceKnownType的类型。

例如:

我有动物界面:

 public interface IAnimal { string Name { get; } void MakeSound(); } 

和实现(接口不知道实现类型):

 public class Cat : IAnimal { public string Name =>"Kitty"; public void MakeSound() { Console.WriteLine("Meeeee-ow!"); } } public class Dog : IAnimal { public string Name => "Lucy"; public void MakeSound() { Console.WriteLine("Wolf Wolf!"); } } 

要使用在服务中实现IAnimal接口的CatDog类型:

 public interface IAnimalService: IAnimalService { IAnimal GetDog(); void InsertCat(IAnimal cat); } 

我可以使用ServiceKnownType属性,它将按接口类型加载类型。

我创建了一个返回所有IAnimal类型的静态类:

  public static class AnimalsTypeProvider { public static IEnumerable GetAnimalsTypes(ICustomAttributeProvider provider) { //Get all types that implement animals. //If there is more interfaces or abtract types that been used in the service can be called for each type and union result IEnumerable typesThatImplementIAnimal = GetAllTypesThatImplementInterface(); return typesThatImplementIAnimal; } public static IEnumerable GetAllTypesThatImplementInterface() { Type interfaceType = typeof(T); //get all aseembly in current application var assemblies = AppDomain.CurrentDomain.GetAssemblies(); List typeList = new List(); //get all types from assemblies assemblies.ToList().ForEach(a => a.GetTypes().ToList().ForEach(t => typeList.Add(t))); //Get only types that implement the IAnimal interface var alltypesThaImplementTarget = typeList.Where(t => (false == t.IsAbstract) && t.IsClass && interfaceType.IsAssignableFrom(t)); return alltypesThaImplementTarget; } } 

并将类AnnimalsTypeProvider和方法GetAnimalsTypes到服务接口属性:

  [ServiceContract] [ServiceKnownType("GetAnimalsTypes", typeof(AnimalsTypeProvider))] public interface IServicesServer : IAnimalService { IAnimal GetDog(); void InsertCat(IAnimal cat); } 

就是这样!

它将在加载服务时以动态模式加载所有IAnimal已知类型,并且它将序列化CatDog而无需任何配置。