Search code examples
wcfwcf-bindingwcf-rest

Enable SOAP And REST On Same WCF Service And Contract


I have an existing wcf SOAP service with basichttpbinding. Now I want to extend it to have one more contract with only rest attributes so that existing method doesn't impact the clients using this contract.

Pasting some major code snippets from the service (excluding unnecessary code), if you need anything, please let me know:

 public interface IMessages
 {
    // existing contract
    [OperationContract(Name = "LoadMessage", IsOneWay = true)]
    void LoadMessage(Guid categoryId, int fileId);

    // new REST contract
    [WebInvoke(Method = "POST",
        UriTemplate = "/LoadMessagesApi/{param}",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped)]
    [Description("Inbound Message")]
    void LoadMessagesApi(string param);
}

public interface IPayment: IMessages { }

Config:

<service name="Services.PaymentService">

    <endpoint address="xmlservice" 
              binding="webHttpBinding"
              behaviorConfiguration="RestBehavior"
              contract="Services.Interfaces.IPayment""/>
    <endpoint address="" binding="wsHttpBinding"
              bindingConfiguration="wsHttpBindingConfig" 
              name="httpGateway" 
              contract="Services.Interfaces.IPayment" />
  </service>
    

<behaviors>
  <serviceBehaviors>
    <behavior name="RestBehavior">
      <!--Behaviour for REST endpoint for HELP enability-->
      <webHttp helpEnabled ="true"></webHttp>
    </behavior>
  </endpointBehaviors>
</behaviors>

But I get this error:

Operation 'LoadMessage' of contract 'IMessages' 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.

Why am I getting bodystyle error on the first contract where I haven't added webget or webinvoke attribute? Can someone point please?


Solution

  • There is a problem with your service interface. In a ServiceContract, if one of the methods uses WebInvoke, other methods need to use WebInvoke or webget, so the solution is to add WebInvoke or webget to LoadMessage, or modify the WebInvoke above LoadMessagesApi to OperationContract.