【发布时间】:2016-02-11 11:34:46
【问题描述】:
关于 WCF 中的接口和泛型有很多关于 SO 的问题,但我找不到一个与我有相同问题的问题。
我有一项合同服务:
[ServiceContract]
[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))]
public interface IService :
{
[OperationContract]
ICollectionWrapper<IAssociation> FindAssociation(string name, int pageSize, int page);
}
public interface ICollectionWrapper<TModel>
{
int TotalCount { get; set; }
IEnumerable<TModel> Items { get; set; }
}
[KnownType(typeof(OrganizationDto))]
[KnownType(typeof(CompanyDto))]
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
[DataMember]
public int TotalCount { get; set; }
[DataMember]
public IEnumerable<TModel> Items { get; set; }
}
public class CompanyDto : IAssociation
{
public int Id { get; set; }
public string Name { get; set; }
}
public class OrganizationDto : IAssociation
{
public int Id { get; set; }
public string Name { get; set; }
}
它与ChannelFactory<IService> 一起使用,上面的代码效果很好。但现在我想在服务中添加另一个方法,它也返回ICollectionWrapper<T>。
[OperationContract]
ICollectionWrapper<ICustomer> Search(ISearchQuery searchQuery);
所以我像注册另一个一样注册它:
[ServiceContract]
[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))]
[ServiceKnownType(typeof(CollectionWrapper<ICustomer>))] // This line creates the error.
public interface IService :
{
[OperationContract]
ICollectionWrapper<IAssociation> FindAssociation(string name, int pageSize, int page);
[OperationContract] // New method.
ICollectionWrapper<ICustomer> Search(ISearchQuery searchQuery);
}
[KnownType(typeof(OrganizationDto))]
[KnownType(typeof(CompanyDto))]
[KnownType(typeof(CustomerDto))] // New model.
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
[DataMember]
public int TotalCount { get; set; }
[DataMember]
public IEnumerable<TModel> Items { get; set; }
}
一旦我有两个ServiceKnownTypes 和CollectionWrapper,服务就会失败并出现以下错误:
底层连接已关闭:发生意外错误 一个接收。
还有内部异常:
一个现有的连接被远程主机强行关闭。
我可以在这两行代码之间切换(删除一行,添加另一行):
[ServiceKnownType(typeof(CollectionWrapper<ICustomer>))]
[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))]
然后每个方法都起作用,但不能同时进行。知道如何让它工作吗?我不想使用具体的类。
这是我尝试过的(但失败了):
[ServiceKnownType(typeof(CollectionWrapper<object>))]
[ServiceKnownType(typeof(CollectionWrapper<>))]
我还尝试为 IAssociation 和 ICustomer 分配一个通用接口,但它也不起作用。
[ServiceKnownType(typeof(CollectionWrapper<ISomething>))]
它适用于 IEnumerable<T> 和 IList<T> 但不适用于我的 ICollectionWrapper<T>
编辑:
ICustomer 和 IAssociation(以及它们的实现)没有任何共同之处。它们不相互继承任何东西,也没有任何其他共同的依赖关系。
【问题讨论】:
-
或许内部异常会给你一个更好的线索:Type WcfService1.CollectionWrapper
1[WcfService1.ICustomer]' cannot be added to list of known types since another type WcfService1.CollectionWrapper1[WcfService1.IAssociation]' with the same data contract name' schemas.datacontract.org/2004/07/…' 已经存在。如果存在特定类型的不同集合 - 例如,List<Test>和 Test[],它们不能都添加为已知类型。考虑仅指定其中一种类型以添加到已知类型列表中。 -
一种可能的解决方案是创建,例如,
public class CustomerCollection : ICollectionWrapper<ICustomer>和public class AssociationCollection : ICollectionWrapper<IAssociation>。 -
@jstreet - 感谢您的建议。我已经编辑了我的问题并添加了内部异常。和你说的不一样。您的其他建议可能会起作用,但需要更多执行相同操作的模型,我想避免这样做。但这是一个很好的最后手段。
-
嗯,你发布的内部异常也没有解释太多......也许除了类型冲突之外你还有其他问题。我提出的解决方案确实有效。但我认为这里真正的解决方案是你需要弄清楚你的类/接口层次结构。