Skip to content

rasor/wcf-rest

Repository files navigation

wcf-rest

HowTo create a REST service from a WCF service including Swagger.yaml

IBookService.yaml

If you have an existing service you create yet an endpoint so you can keep the existing service.

In most cases the best thing is to create yet a WCF service using the same contract as your original WCF service. Just start from bullet 2 then.

The templates

  1. Create an empty web:
  • File - New - Project - ASP.NET Web Application - Empty
  • => This gives you a project without Global.Ajax and startup files
  1. Add Ajax-enabled WCF service
  • Solution - RightClick project - Add - New Item (Ctrl-Shft-A) - WCF Service (Ajax-enabled) - You could call it RestService1
  • => This gives you a WCF service with webHttpBinding and a ref to System.ServiceModel.Web

The first response

  1. Change from SOAP to REST response
  • In RestService1.svc.cs add below [OperationContract]:
[WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]

Change response to <empty> for void functions

  1. Change from Ajax to REST client

Add Sample Interface

  1. Add a sample interface
	public class RestService1 : IBookService
  • Click on LigthBulp - Implement Interface
  1. Change contract. In web.config change from <service contract="WebApplicationWcfRest1.RestService1
    to <service contract="WebApplicationWcfRest1.interfaces.IBookService
  2. Implement GetBookById(). Add line:
	return new Book() {Id = 1, Name= "The incredible stamp" };
  1. Debug project (F5)

Create Swagger Yaml

  1. Create Swagger.yaml - this is the wsdl for REST
  • In Project Properties (Alt-Enter) - Build - Select XML Documentation file - Clear the path
  • Install https://www.nuget.org/packages/Swagger4WCF into the project containing the interfaces
  • Build project
  • => The yaml file is in \bin\WebApplicationWcfRest1.IBookService.yaml
  1. Edit yaml file
  • Replace host from localhost to localhost:15563 (or to the test- or prod server host)
  • Replace basePath from /IBookService to /RestService1.svc
  • Replace all paths from e.g. /GetBooksList: to /Book: (as you wrote in UriTemplate)
  • Group operations with same path together and delete the duplicate paths
  • Those paths having path parameters e.g. /{id} change parameters from in: query to in: path
  • Save the yaml file into \interfaces\ - update version number each time you send a new version to the client
  1. Test the yaml file
  • Goto http://editor.swagger.io/
  • Replace left pane with the content of the yaml file (if you use chrome, you can paste)
  • => In top of right pane: The should be no errors

Move contracts to new library

  1. Swagger4WCF does not work well with Unity.WCF, so we move the contracts to a new library
  • File - New - Project (Ctrl-Shft-N) - Class Library - Name: Contracts
  • Drag'n'drop folder interfaces to Contracts
  • Drag'n'drop folder models to Contracts
  • Add Refs to project Contracts:
    • System.ServiceModel
    • System.ServiceModel.Web
    • System.Runtime.Serialization
  1. Create Swagger.yaml - this is the wsdl for REST
  • In Project Properties (Alt-Enter) - Build - Selt "XML Documentation file" - Clear the path
  • Install https://www.nuget.org/packages/Swagger4WCF into the project containing the interfaces (Contracts)
  • Build project
  • => The yaml file is in \bin\WebApplicationWcfRest1.IBookService.yaml
  1. Remove Swagger4WCF from project WebApplicationWcfRest1
  • In project WebApplicationWcfRest1 add ref to project Contracts
  • In packages.config remove line having Swagger4WCF
  • Rebuild Solution

Add dependency injection with Unity

  1. Remove Swagger4WCF from service project
  • Unload project WebApplicationWcfRest1
    • Remove two lines containing Swagger4WCF near bottom
  1. Add dependency injection
  • Install https://www.nuget.org/packages/Unity.Wcf into the project containing the services (WebApplicationWcfRest1)
  • => This created file WcfServiceFactory.cs
  • View Markup of RestService1.svc
  • Replace: CodeBehind="RestService1.svc.cs"
    • with: Factory="WebApplicationWcfRest1.WcfServiceFactory"
  • In WcfServiceFactory.cs register the service:
               .RegisterType<IBookService, RestService1>();
  • Build the solution
  1. Debug project (F5)

Use HTTP Status Codes

  1. Add HTTP Status Codes to your service
  • In your service RestService1.svc.cs - method AddBook() add content
            WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Created; // 201
            if (book.Name == "The incredible stamp") {   // Book exist
                WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.Conflict; // 409
            }
  • In method UpdateBook() add content
            if (book.Id == 2) { // Book does not exist - 404
                WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound("Resource not found");
            } else if (book.Name == "") { // Invalid request
                WebOperationContext.Current.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.MethodNotAllowed; // 405
            }
  • In method GetBookById() add content
            if (id == "2") { // Book does not exist - 404
                WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound("Resource not found");
                return null;
            } else {
                return new Book() { Id = 1, Name = "The incredible stamp" };
            }
  1. Update your yaml with the Status Codes
  • In IBookService.yaml
    put:
      responses:
        201:
          description: "Book created"
        409:
          description: "Book exist"
    post:
      responses:
        404:
          description: "Book not found"
        405:
          description: "Validation exception"
    get:
      responses:
        404:
          description: "Book not found"

Refs

The End