Generic ServiceContract

2019-07-29 07:43发布

[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?

3条回答
啃猪蹄的小仙女
2楼-- · 2019-07-29 08:11

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

查看更多
迷人小祖宗
3楼-- · 2019-07-29 08:21

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> { }.

查看更多
小情绪 Triste *
4楼-- · 2019-07-29 08:27

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

查看更多
登录 后发表回答