Tuesday, April 23, 2013

Auto Generated WCF Client Not Able to Direct Call WebHttpBinding Service

I have a WCF service hosted with WebHttpBinding. The service is very simple, an operation contract which accept multiple parameters. My WCF client, auto generated after using the "Add Service Reference", is not able to directly consume the WCF service. The error only occur for WebHttpBinding but not the others.

Here's the story. This is how I decorate my operation contract:


[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "Submit2String", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
string Submit2String(string input1, string input2);


After that, I created a unit test project. And then, add the service reference to my unit test project. Finally, I wrote the following code to call my service.


ExpenseServiceClient proxy = new ExpenseServiceClient();
proxy.Submit2String("test1", "test2");


When I test run my above code, I get the following error:

Error: InvalidOperationException was unhandled by user code
Manual addressing is enabled on this factory, so all messages sent must be pre-addressed.



Here is how my auto generated configuration file look like after using the "Add Service Reference":


<system.serviceModel>
  <bindings>
    <webHttpBinding>
      <binding name="webHttp">
        <security mode="None">
          <transport clientCredentialType="None" />
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <client>
    <endpoint binding="webHttpBinding" bindingConfiguration="webHttp"
        contract="ExpenseService.IExpenseService" address="http://localhost:65000/ExpenseService.svc">
    </endpoint>
  </client>
</system.serviceModel>


I realize that only WebHttpBinding has this problem. The solution is simple, just add a behavior configuration as follow:


<behaviors>
  <endpointBehaviors>
    <behavior name="webEndpoint">
      <webHttp defaultBodyStyle="Wrapped" defaultOutgoingResponseFormat="Json" helpEnabled="true"/>
    </behavior>
  </endpointBehaviors>
</behaviors>


Then, update the client endpoint to use the above endpoint behavior.


<client>
  <endpoint binding="webHttpBinding" bindingConfiguration="webHttp" behaviorConfiguration="webEndpoint"
      contract="ExpenseService.IExpenseService" address="http://localhost:65000/ExpenseService.svc">
  </endpoint>
</client>


The problem is solved.



5 comments:

  1. Thank you! This solved it for me! I really appreciate your clear definition of the problem and solution.

    ReplyDelete
  2. THANK YOU!!!. I will start follow you

    ReplyDelete
  3. Thanks but, I got one more Error is
    The remote server returned an error: (405) Method Not Allowed. what will i do ? say

    ReplyDelete
    Replies
    1. Are you decorating your service method with WebGet? If yes, the service is expecting a HTTP GET, but the default WCF service call is HTTP POST. Therefore, please use WebChannelFactory. More info, please refer to: http://sylvester-lee.blogspot.com/2013/05/wcf-rest-service-httpclient-vs-wcf.html

      Delete
  4. Muchas Gracias, problema resuelto!

    ReplyDelete

Send Transactional SMS with API

This post cover how to send transactional SMS using the Alibaba Cloud Short Message Service API. Transactional SMS usually come with One Tim...