如果我正在使用包含“OperationContract”操作的“ServiceContract”。 操作返回或接收的接口参数。 当我使用该服务时,我收到一条异常消息:
“反序列化器不知道任何映射到此名称的类型。如果您使用的是DataContractSerializer,请考虑使用DataContractResolver,或者将对应于'{%className%}'的类型添加到已知类型列表中。” p>
我可以将KnowTypes的属性添加到接口,但是我的接口项目与实现项目分离,并且它们不能具有循环依赖性引用,因此无法声明KnowTypes。
什么是最佳解决方案?
答案 0 :(得分:0)
不幸的是,这是不可能的。类似的问题已经被问到:Using Interfaces With WCF
答案 1 :(得分:0)
我找到了一个解决方案并且它已经有效了!
我使用ServiceKnownType
加载了为ServiceKnownType
成员实施DataContract
的类型。
例如:
我有动物界面:
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!");
}
}
使用在服务中实现Cat
接口的Dog
和IAnimal
类型:
public interface IAnimalService: IAnimalService
{
IAnimal GetDog();
void InsertCat(IAnimal cat);
}
我可以使用将按接口类型加载类型的属性ServiceKnownType
。
我创建了一个返回所有IAnimal
类型的静态类:
public static class AnimalsTypeProvider
{
public static IEnumerable<Type> 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<Type> typesThatImplementIAnimal = GetAllTypesThatImplementInterface<IAnimal>();
return typesThatImplementIAnimal;
}
public static IEnumerable<Type> GetAllTypesThatImplementInterface<T>()
{
Type interfaceType = typeof(T);
//get all aseembly in current application
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
List<Type> typeList = new List<Type>();
//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
已知类型,并且无需任何配置即可序列化Cat
和Dog
。