2

REST Only accepts String..?

So What I do is make a string exposed contract and convert it server side, and pass it to my method which SOAP was directly calling. Which works. ( I can call REST from firefox)

BUT now, I cannot expose my SOAP OperationContract with out causing a problem with the error:

Operation 'GetServices' of contract 'IServices' 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.

Below are my 3 exposed methods. Only when I hide the 3rd will REST work. Removing my SOAP connection.. ( I belive it wants REST setup on the 3rd method and as its not been defined, fails to understand it)

    // REST
    [OperationContract]
    [WebGet(UriTemplate = "GET/Services/{CostCentreNo}/{Filter}")]
    List<Services> RestGetServices(String CostCentreNo, String Filter);

    // REST
    [OperationContract]
    [WebGet(UriTemplate = "GET/ServiceDetails/{CostCentreNo}/{ServiceCode}/{Recurring}")]
    List<ServiceDetails> RestGetServiceDetails(String CostCentreNo, String ServiceCode, String Recurring);

    // SOAP
    [OperationContract]
    List<Services> GetServices(Int32 CostCentreNo, Int32 Filter);

Surely I can make just one contract method, which allows me to call either SOAP OR REST.

IAmGroot
  • 13,760
  • 18
  • 84
  • 154

2 Answers2

3

As mentioned in Can I pass non-string to WCF RESTful service using UriTemplate? :

UriTemplate variables in the path always resolve to strings when using WebGet or WebInvoke. You can only bind UriTemplate variables to int, long, etc. when they are in the query portion of the UriTemplate.

This is taken from the answer ( Can I pass non-string to WCF RESTful service using UriTemplate? ), bold formatting is mine...

So an example of a REST and SOAP accessable method:

// REST AND SOAP
[OperationContract]
[WebGet(UriTemplate = "/Services?CostCentreNo={CostCentreNo}&Filter={Filter}")]
List<Services> GetServices(Int32 CostCentreNo, Int32 Filter);

Which is accessible by

http://localhost:1337/WCF.IService.svc/rest/Services?CostCentreNo=1&Filter=1

Community
  • 1
  • 1
Ron Klein
  • 9,178
  • 9
  • 55
  • 88
  • The only problem with this is that it doesn't follow the normal conventions for RESTful urls. Services like angular-resource which depend on a base URL like `/item/:id` and then only the HTTP methods change. If you have a non-changing base url like `item?id=:id` WCF now complains that WebGet/WebInvoke methods cannot vary their uritemplate only by query parameters. You wind up defining `items?page=:pageNum&count=:count` and `item?id=:id`. We no longer have a common URL identifying the resource or resource type that we are working with. – Richard Collette May 13 '14 at 13:22
2

REST only accepts string

No that is not true. Parameters mapped to URL template can be any basic type. WCF will make conversion for you. If you use WebInvoke instead of WebGet and you will use PUT or POST method you can even pass whole serializable objects inside requests.

Ron Klein
  • 9,178
  • 9
  • 55
  • 88
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670