通用服务合同
[ServiceContract]
public interface ISecurities<T> : IPolicyProvider where T: EntityObject
{
[OperationContract(Name="GetAllSecurities")]
IEnumerable<T> GetSecurities();
[OperationContract]
IEnumerable<T> GetSecurities<T1>(List<T1> lstIdentifiers) where T1 : FI_CusipMaster;
[OperationContract]
T GetSecurity<T1>(T1 lstIdentifiers) where T1 : FI_CusipMaster;
}
//Host
///CADIS Contract
ServiceHost dmHost = new System.ServiceModel.ServiceHost(typeof(GlobalInvestors.FIPA.BLL.UDI.CADISSecurities));
Uri baseAddress = dmHost.BaseAddresses[0];
Uri policyAddress = new Uri(baseAddress.AbsoluteUri.Replace(baseAddress.AbsolutePath, ""));
dmHost.AddServiceEndpoint(
typeof(GlobalInvestors.FIPA.BLL.IPolicyProvider),
new System.ServiceModel.WebHttpBinding(),
policyAddress).Behaviors.Add(new System.ServiceModel.Description.WebHttpBehavior());
dmHost.Open();
//App.Config
<service behaviorConfiguration="UDIBehaviour" name="GlobalInvestors.FIPA.BLL.UDI.CADISSecurities">
<endpoint binding="basicHttpBinding" contract="GlobalInvestors.FIPA.BLL.UDI.ICADISSecurities" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:1667/CADIS" />
</baseAddresses>
</host>
</service>
<behavior name="UDIBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
[ServiceContract]
[ServiceKnownType(typeof(SecurityMasterAdapter))]
public interface ICADISSecurities :ISecurities<SecurityMasterAdapter>
{
}
我收到“InvalidDataContractException 类型 'System.Collections.Generic.List`1[T1]' 无法导出为架构类型,因为它是开放泛型类型。只有当其所有泛型参数类型都是实际类型时,才可以导出泛型类型”。如果我主持这份合同。
我读到,在 ServiceContract 中避免泛型是很好的。但是可以用T吗?
[ServiceContract]
public interface ISecurities<T> : IPolicyProvider where T: EntityObject
{
[OperationContract(Name="GetAllSecurities")]
IEnumerable<T> GetSecurities();
[OperationContract]
IEnumerable<T> GetSecurities<T1>(List<T1> lstIdentifiers) where T1 : FI_CusipMaster;
[OperationContract]
T GetSecurity<T1>(T1 lstIdentifiers) where T1 : FI_CusipMaster;
}
//Host
///CADIS Contract
ServiceHost dmHost = new System.ServiceModel.ServiceHost(typeof(GlobalInvestors.FIPA.BLL.UDI.CADISSecurities));
Uri baseAddress = dmHost.BaseAddresses[0];
Uri policyAddress = new Uri(baseAddress.AbsoluteUri.Replace(baseAddress.AbsolutePath, ""));
dmHost.AddServiceEndpoint(
typeof(GlobalInvestors.FIPA.BLL.IPolicyProvider),
new System.ServiceModel.WebHttpBinding(),
policyAddress).Behaviors.Add(new System.ServiceModel.Description.WebHttpBehavior());
dmHost.Open();
//App.Config
<service behaviorConfiguration="UDIBehaviour" name="GlobalInvestors.FIPA.BLL.UDI.CADISSecurities">
<endpoint binding="basicHttpBinding" contract="GlobalInvestors.FIPA.BLL.UDI.ICADISSecurities" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:1667/CADIS" />
</baseAddresses>
</host>
</service>
<behavior name="UDIBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
[ServiceContract]
[ServiceKnownType(typeof(SecurityMasterAdapter))]
public interface ICADISSecurities :ISecurities<SecurityMasterAdapter>
{
}
I get "InvalidDataContractException Type 'System.Collections.Generic.List`1[T1]' cannot be exported as a schema type because it is an open generic type. You can only export a generic type if all its generic parameter types are actual types." if I host this contract.
I have read that it is good to avoid generics in ServiceContract. but is it possible to use T?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这种情况下,您的问题不是 ServiceContract 中的 T,而是用作 DataContract 的 T1。如果在服务合约实现过程中将 T 替换为特定类型,则可以在服务合约中使用 T。对于数据契约(操作参数和返回类型),您根本不能使用 T。您始终必须指定具体类型。可以使用 ServiceKnownTypeAttribute 重写您的服务合同,以便将 T1 替换为 FI_CusipMaster,并且 ServiceKnownType 指定从 FI_CusipMaster 派生的所有可能的类。
编辑: 另一种方法是不使用 ServiceKnownType 并使用必须在 FI_CusipMaster 类型上定义的 KnownTypeAttribute。
最好的问候,拉迪斯拉夫
Your problem in this case is not T in ServiceContract but T1 used as DataContract. You can use T in service contract if you replace T with specific type during service contract implementation. For data contracts (operation parameters and return types) you can't use T at all. You always have to specify concrete type. Your service contract can be rewritten with usage of ServiceKnownTypeAttribute so that T1 is replaced with FI_CusipMaster and ServiceKnownType specifies all possible classes derived from FI_CusipMaster.
Edit: Another way is not to use ServiceKnownType and use KnownTypeAttribute which has to be defined on FI_CusipMaster type.
Best regards, Ladislav
正如错误所示,不,您不能使用 T。服务契约需要能够写出处理确定类型的序列化信息。它无法处理导出函数中的开放泛型
As the error says, no you cannot use T. Service contracts need to be able to write out serialization information that deals with definitive types. It can't handle open generics in the exported functions
在您的示例中,T 是通用类型。不能在 ServiceContract 中使用泛型类型,除非它与已定义的类型参数一起使用 - 如
class Foo : List; 中所示。 { }
。In your example T is a generic type. You cannot use a generic type in a ServiceContract unless it is used with a defined type parameter- as in
class Foo : List<int> { }
.