WCF服务将某些功能公开为REST

时间:2012-11-06 13:36:11

标签: wcf rest soap behavior endpoint

我有一个带有大约100个函数的WCF SOAP服务。我只想将其中一些暴露给REST端点。只用一份合同就可以做到这一点吗?

我添加了一个休息行为和休息端点,如下所示:

<behaviors>
      <endpointBehaviors>
        <behavior name="RestBehavior">
          <webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>


<endpoint address="json" binding="webHttpBinding" behaviorConfiguration ="RestBehavior" contract="Test.IService" />
<endpoint address="" binding="customBinding" bindingConfiguration="BufferedHttpBinaryBusiness"
          bindingName="BufferedHttpBinaryBusiness" contract="Test.IService" />

并将WebGet属性添加到我想在rest端点上公开的函数:

<WebGet(BodyStyle:=WebMessageBodyStyle.Wrapped, RequestFormat:=WebMessageFormat.Json, ResponseFormat:=WebMessageFormat.Json, UriTemplate:="/IsRegistered?Id={Id}")>
    <ServiceModel.OperationContract()>
    Function IsRegistered(ByVal Id As String) As Boolean

但我也有其他功能,我不想透露为REST。

<ServiceModel.OperationContract()> 
Function GetName(ByVal x As Long, ByVal y As String) As String
<ServiceModel.OperationContract()> 
Function GetId(ByVal name As String) As String

我得到的错误是:

System.InvalidOperationException: Operation 'GetName' of contract 'IService' specifies multiple request body parameters to be serialized without any wrapper elements. At most one body parameter can be serialized without wrapper elements. Either remove the extra body parameters or set the BodyStyle property on the WebGetAttribute/WebInvokeAttribute to Wrapped.
   at System.ServiceModel.Description.WebHttpBehavior.TryGetNonMessageParameterType(MessageDescription message, OperationDescription declaringOperation, Boolean isRequest, Type& type)
   at System.ServiceModel.Description.WebHttpBehavior.ValidateBodyStyle(OperationDescription operation, Boolean request)
   at System.ServiceModel.Description.WebHttpBehavior.<>c__DisplayClass10.<>c__DisplayClass13.<GetRequestDispatchFormatter>b__d()
   at System.ServiceModel.Description.WebHttpBehavior.<>c__DisplayClass10.<GetRequestDispatchFormatter>b__c()
   at System.ServiceModel.Description.WebHttpBehavior.HideReplyMessage(OperationDescription operationDescription, Effect effect)
   at System.ServiceModel.Description.WebHttpBehavior.GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
   at System.ServiceModel.Description.WebHttpBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
   at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
   at System.ServiceModel.ServiceHostBase.InitializeRuntime()
   at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

当我将WebGet属性添加到此函数时,另一个soap函数会发生相同的错误。它似乎需要我将WebGet属性应用于所有函数。换句话说,它要求我公开契约中的所有函数以暴露给REST端点。但我只希望其中一些作为REST进行表达。不可能吗?

1 个答案:

答案 0 :(得分:4)

简而言之,没有。您必须有两个不同的合同才能使SOAP和REST协同工作。您可以在同一个配置中添加两个端点。好处是你只需要在一个单独的接口/契约中定义REST操作,并让你从该接口继承服务,而不必更改你的代码。

以下文章是一个很好的解释,以及在您的服务中实现这两者的方法。我在我写的两个自己的服务中用它作为例子。

How to enable REST and SOAP both on the same WCF service