11

I'm trying to build a C# service in .NET 3.5 that supports both SOAP - and shows the WSDL - and REST.

The SOAP service and WSDL generation was easy enough to do using the ServiceHost and a BasicHttpBinding classes. Got that working and the client was happy.

Because the SOAP calls all used simple parameters, the client developers requested a REST interface for some of the commands. So I changed the ServiceHost class to a WebServiceHost, added necessary WebInvoke and WebGet attributes, added a WebHttpBinding class, and bingo - REST and SOAP were both working out of one service. Way cool, change one interface and both REST and SOAP got the new stuff.

But one problem - the WSDL no longer gets generated. I couldn't browse to http://server/service?wsdl and get the WSDL file. Checking the MSDN docs, that appears to be behavior for a default WebServiceHost.

Question: can I override this behavior so that the WSDL could be obtained? Doesn't have to the same URL as before - it can change - but I just need to have some URL into service to get the WSDL for those SOAP developers.

Jason Swager
  • 6,421
  • 6
  • 41
  • 56
  • Hello Jason, i would LOVE to know if you are still using this approach and how its working or not working for you. Are you finding that you have to duplicate any methods (the core logic) for supporting both? – schmoopy Jan 26 '12 at 20:08
  • I just had to create two endpoints and add an extra attribute to each command. – Jason Swager Jan 26 '12 at 20:28
  • similar problem with solution. http://social.msdn.microsoft.com/Forums/en/wcf/thread/845d0bbd-52b4-420f-bf06-793d53ef93ba – maciejW Oct 17 '10 at 01:47

3 Answers3

4

When you say "added a WebHttpBinding class", it sounds like you are doing a lot of the configuration in code as opposed to in configuration files.

If this is the case, you could try moving the configuration to the configuration file. Then create 2 endpoints for the contract one REST and one SOAP, with 2 different addresses and bindings.

Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • I do all the configuration in code, not configuration files. One solution is to use two endpoints - and that solution does work just fine. I was hoping to use a single endpoint; a single port and root URL. – Jason Swager Nov 13 '09 at 20:06
  • 1
    I dont think that you can get a WSDL out of a WebHttpBinding Endpoint. – Shiraz Bhaiji Nov 13 '09 at 20:09
4

But one problem - the WSDL no longer gets generated. I couldn't browse to http://server/service?wsdl and get the WSDL file. Checking the MSDN docs, that appears to be behavior for a default WebServiceHost.

Yes - that's one of the drawbacks of REST - no more WSDL, no more machine-readable service description. You need to hope the service provider gives you a usable and up to date documentation on what you can do.

There's no WSDL for REST - period. Can't be turned on or anything - it just doesn't exist.

There are some efforts under way to provide something similar - called WADL (Web Application Description Language), but as far as I know, it's still far from an established standard by any means. Also see: Do we need WADL?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I can understand that REST would have no WSDL, but keep in mind that the service is handling both REST and SOAP requests at the same time. It's just that the SOAP clients can't request a WSDL anymore. The goal was to have a single service, with a single listening port, that could service both REST, SOAP and WSDL, all based on URL path. – Jason Swager Nov 16 '09 at 15:53
0

Circa, 2007, WSDL v2.0 is supposed to be able to describe RESTful services. I have found that with WCF in .Net v4.0, that the WDSL generated from a purely RESTful service is invalid (WSDL v1.0?).

I created a similar project that exposes both SOAP and RESTful endpoints, and enabled this by, as you did, modifying the interface as such:

    // Get all Categories - complex object response
    [OperationContract]                             // categories
    [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllCategories")]
    CategoryCollection GetAllCategories();          // SubSonic object
    [OperationContract]                             // categories - respond with a JSON object
    [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllCategories.JSON")]
    CategoryCollection GetAllCategoriesJSON();      // SubSonic object

One caveat to this is that all input parameters now must be of type string for all SOAP requests.

Any way of getting around this?

ElHaix
  • 12,846
  • 27
  • 115
  • 203
  • Is there a way to expose exactly the same method in SOAP and REST instead of adding a new method for each old soap method? – Bishoy Hanna Nov 11 '15 at 03:52