1

我有一个包含大约 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并为我想在休息端点上公开的函数添加了属性:

<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 属性添加到此函数时,另一个肥皂函数会发生相同的错误。似乎它需要我将 WebGet 属性应用于所有函数。换句话说,它要求我公开合约中的所有函数以公开给 REST 端点。但我只希望其中一些以 REST 形式出现。不可能吗?

4

1 回答 1

4

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

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

如何在同一个 WCF 服务上同时启用 REST 和 SOAP

于 2012-11-06T21:51:57.670 回答