WCF单一服务多个合同和泛型,可能吗?

时间:2011-03-02 18:44:08

标签: wcf web-services generics

我是否可以使用泛型拥有多个端点和多个合同的单个服务。我遇到了无法创建元数据的问题(它可能只是一个配置问题而不确定我的基本主机地址需要看起来像):

    namespace WCFSingleService
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
        [ServiceContract]
        public interface ISingleService<T>
        {
            [OperationContract]
            T GetData(T item);

         }   

    }

namespace WCFSingleService
{
    [ServiceContract(Name = "User")]
    public interface IUserSingleService: ISingleService<User>
    {
    }
}

namespace WCFSingleService
{
    [ServiceContract(Name = "Some")]
    public interface ISomeSingleService: ISingleService<Some>
    {
    }
}

public partial class SingleService : IUserSingleService
    {
        public User GetData(User item)
        {
            //Do something
        }



    }

public partial class SingleService : ISomeSingleService
    {
        public Some GetData(Some item)
        {
            //Do something
        }



    }

这可能吗?这项服务的配置是什么样的?另外,我能否从AJAX客户端使用该服务?我想我会因为我没有尝试将类型传递给合同而且每个合同都有自己的端点,对吧?谢谢!

这是我目前的配置:

<system.serviceModel>
    <services>
      <service name="WCFSingleService.SingleService" behaviorConfiguration="WCFSingleService.ServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress = "http://localhost:8732/Design_Time_Addresses/WCFSingleService/SingleService" />            
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- Unless fully qualified, address is relative to base address supplied above -->
        <endpoint address="User" binding="wsHttpBinding" contract="WCFSingleService.IUserSingleService"/>
        <endpoint address="Some" binding="wsHttpBinding" contract="WCFSingleService.ISomeSingleService"/>




        <!-- Metadata Endpoints -->
        <!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --> 
        <!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFSingleService.ServiceBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

更新 好吧,我想知道为什么我的服务不是;一旦我打开调试,就开始了,这打开了错误dorr。 DUH!无论如何,我遇到的问题与为两个服务创建的相同方法名称有关。那么,有没有人知道如果多个服务阻止相同的接口,WCF重命名方法名称的方法?我可以在其中一个实现中放置一个装饰,使其看起来不同吗?

3 个答案:

答案 0 :(得分:1)

是的,您可以拥有多个合同的单一服务,您必须在服务接口上设置ConfigurationName。

你需要像这样声明你的界面

Namespace ServiceNameSpace

<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0"), _
     System.ServiceModel.ServiceContractAttribute([Namespace]:="whatever namespace you like", ConfigurationName:="ServiceContract1")> _
    Public Interface ServiceContract1
    <System.ServiceModel.OperationContractAttribute(Action:="Service Action"), _
         System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults:=True)> _
        Function ServiceFunction1(ByVal var As Class1) As Class1

End Interface



 <System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0"), _
     System.ServiceModel.ServiceContractAttribute([Namespace]:="temp namespace", ConfigurationName:="ServiceContract2")> _
    Public Interface ServiceContract2

<System.ServiceModel.OperationContractAttribute(Action:="Service Action"), _
         System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults:=True)> _
        Function function2(ByVal var As Class2) As Class2
End INterface

End Namespace

那么你需要一个实际上已经实现了你所暴露的服务合同的类

namespace ServiceNameSpace

Public Class ServiceImplementationCLass Implements ServiceContract1, ServiceContract2

Public Function ServiceFunction1(byval var as class1) as class1

'Do whatever you want to 

end Function

Public Function function2(byval var as class2) as class2

'Do whatever you want to 

end Function

end namespace

end Class

最后只需配置下面的服务

<system.serviceModel>
    <services>

<service name="ServiceNameSpace.ServiceImplementationCLass" behaviorConfiguration="ServiceBehavior">
                <endpoint address="" binding="basicHttpBinding" contract="ServiceContract1" />
                <endpoint address="" binding="basicHttpBinding" contract="ServiceContract2" />
</service>
</services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

上面的代码是在VB.NET中,如果你想我也可以为你提供C#代码,

我希望我的解决方案可以帮助你。

答案 1 :(得分:0)

我必须和No。

一起

我试图让服务返回一个接口,因为它可以返回几种类型。最后它回应像返回的对象(严重)。

相反,我为每个可能的返回类型实现了不同的回调函数:

[ServiceContract(CallbackContract=typeof(IClientFeedback))]
public interface IDataService
{
    [OperationContract]
    void GetItem(string entryID);
}

[ServiceContract]
public interface IClientFeedback
{
    [OperationContract(IsOneWay = true)]
    void ReturnMailMessage(MailMessage msg);

    [OperationContract(IsOneWay = true)]
    void ReturnContact(Contact cont);
}

我知道它并不完全相同,但如果界面不起作用,我认为仿制药的可能性更小。

答案 2 :(得分:0)

我想出了我想要完成的事情。基本上,我仍然可以设置我的代码,以便在使用一个服务时使用泛型。我得到了单一服务here的想法。然后我意识到我需要在部分类SingleService(不是接口本身)上指定ServiceContract,并使用OperationContract(Name =“TheExposedNameOfTheMethod”)修饰我实现的方法。以下是一些代码:

public interface ISingleService<T>
    {
        //[OperationContract]
        T GetData(T item);


    }


public interface IUserSingleService: ISingleService<User>
    {
    }

public interface IOtherSingleService: ISingleService<Other>
    {
    }

[ServiceContract]
    public partial class SingleService : IUserSingleService
    {
        [OperationContract(Name = "GetDataUser")]
        public User GetData(User item)
        {
            switch(item.MessageCommand)
            {
                case "Create":
                    //do stuff to for a User create
                    break;
                case "Update":
                    //do stuff to for a User update
                    break;
                case "Delete":
                    //do stuff to for a User Delete
                    break;
            }

            return item;

        }



    }

//You only need to specifc the ServiceContract attribute in one of the partial classes
        public partial class SingleService : IOtherSingleService
    {
        [OperationContract(Name = "GetDataOther")]
        public Other GetData(Other item)
        {
            ...do something
            return item;

        }



    }

这是端点的样子:

<endpoint  binding="basicHttpBinding" name="TheService"
          contract="SingleService" />