views:

50

answers:

1

I have a simple WCF service that I call server side from code behind via a service reference. It's used for validation and works and was automatically setup by Visual Studio and is using SOAP I think because the binding is wsHttpBinding.

I want to use the same WCF service, but call it client side from jQuery using ajax(). I'm trying to implement it by way of these instructions.

But if I make the changes to get the client side call working, I have to add the decoration below which I think will break what works on the server side and also change the system.serviceModel section in web.config.

[WebInvoke(Method = "POST",
    BodyStyle = WebMessageBodyStyle.Wrapped,
    ResponseFormat = WebMessageFormat.Json,
    RequestFormat= WebMessageFormat.Json) ]

How do I have a WCF service that can be called both from the server-side and client side (jQuery/ajax)?

Or put another way, this may be incorrectly worded, can an endpoint have multiple bindings?

A: 

An endpoint in WCF has an ABC

  • Address
  • Binding
  • Contract

So therefore: no, a single endpoint cannot have multiple bindings. But you can have multiple endpoints for the same contract!

So if you want to expose two methods with basically the same functionality over SOAP and REST, you need to have two endpoints.

You can define your own service method to be callable both from SOAP and REST as shown in that link you mentioned.

What you then need are two separate endpoints:

<services>
   <service name="YourService">
     <endpoint
           address="http://YourServer/YourVirtualDir/YourService.svc"
           binding="wsHttpBinding"
           contract="IYourService" />
     <endpoint
           address="http://YourServer/YourVirtualDir/YourService2.svc"
           binding="webHttpBinding"
           behaviorConfiguration="webCallable"
           contract="IYourService" />
   </service>
</services>

You'll have to define an endpoint behavior that includes the <webHttp/> behavior - or you need to have a *.svc file that uses the WebServiceHost (instead of plain ServiceHost) to host your REST service.

As you can see, you now have two separate endpoints (with two separate *.svc files in a vritual directory), two separate addresses - but both share the same contract (define the same operations).

marc_s
Thanks. I didn't explicitly define or set anything that mentioned REST. Is a service REST by default if you're not using SOAP/xml when you use WCF?
Steve
WebInvoke = REST. And yes - either your service is using SOAP, or then it's using REST - those are the two styles of doing web service calls.
marc_s
One more question - if I have two svc files, I have to duplicate the implementation of the contract, no? Is there a way to have two endpoints with just one svc file?
Steve
@Steve: no, you have two *.svc files that both reference the **same** service class that implements that service contract. One contract, one implementation - two distinct endpoints that expose their functionality to the world. This requires you to have the service implementation in a separate code file (not a *.svc.cs code-behind file) - but that's a best practice anyway :)
marc_s
OK. I put the implementation in a class in another file and had both services inherit from it, so there's one copy of the implementation. Thanks.
Steve