Timuçin
Timuçin

Reputation: 4673

WCF Service exposing some functions as REST

I have a WCF SOAP Service with about 100 functions. I only want to expose some of them to REST endpoints. Isnt it possible to do this with only one contract?

I added a rest behavior and rest endpoint like this:

<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" />

and added WebGet attribute to the function I want to expose on rest endpoint:

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

But I also have my other functions which I dont want to expose as 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

The error I got is:

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)

When I add WebGet attribute to this function, then the same error happens for another soap function. It seems that it requires me to apply WebGet attribute to all functions. In other words, it requires me to expose all functions in contract to expose to REST endpoint. But I want only some of them to expse as REST. Isnt it possible?

Upvotes: 1

Views: 2803

Answers (1)

iMortalitySX
iMortalitySX

Reputation: 1488

In short, no. You must have two different contracts to get both SOAP and REST to work together. You can add both endpoints in the same config though. The good thing is that you just need to define the REST operations in a separate interface/contract and have you service inherit from that interface as well, and you don't have to change your code.

The article below is a great explaination, and way to implement both in your service. I used this as an example in two of my own services that I wrote.

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

Upvotes: 4

Related Questions