Introduction
I was trying to add REST web services to an existing C# application. I could only find information as to how to create a new C# REST app,
but very little on retrofitting older apps. The results below are not complicated but are the culmination of an afternoon's research.
The Solution
First, create a new public interface for the service contract:
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace bob
{
[ServiceContract]
public interface IService
{
[OperationContract]
[WebGet(UriTemplate = "/GetSoftwareVersion", ResponseFormat=WebMessageFormat.Json)]
String GetSoftwareVersion();
}
}
Here, I've defined a new interface called IService
. Note the two
ServiceModel
namespaces I'm using.... very important.
Also, you will need to include the references by the same name into your project.
I then defined a new method I want to call via REST called GetSoftwareVersion
. The
UriTemplate
states what you add (/GetSoftwareVersion)
to the base URI (spec'ed elsewhere, but currently set to 'http://localhost:10870') to form the URI needed to call this method. The
ResponseFormat
stipulates that I want the data returned using JSON format, rather than the standard XML.
Next, I define a class to implement this interface and therefore my REST services.
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace bob
{
public class RestService : IService
{
public String GetSoftwareVersion()
{
return App.Instance.GetSoftwareVersion();
}
}
}
My new class, RestService
, implements the interface, or service contract, I defined earlier. Again, note the
ServiceModel
references.
Since we also have a gSOAP (C++) interface, rather than completely re-jigging the main App class (which has a singleton for external access)
or making the RestService
a singleton itself (which might be useful down the road for other reasons), I just point the REST service to the existing method. Simple and it works.
Next, the app.config needs to be tweaked:
<system.serviceModel>
<services>
<service name="bob.RestService">
<endpoint binding="webHttpBinding" contract="bob.IService"
behaviorConfiguration="webHttp"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Things of note are the service name (bob.RestService
) and endpoint contract (bob.IService
). Point the service name at the REST implementation class and the contract at the interface.
I then "borrowed" the ThreadedServiceHost
class from here,
changed the ServiceHost
class reference to WebServiceHost
, updated the project reference, removed the endpoint and associated code (simplified things),
and made a call to start it from the App()
(constructor) ala:
restHost = new ThreadedWebServiceHost<RestService>(Properties.Settings.Default.REST_ENDPOINT);
REST_ENDPOINT
is simply the base URI where my services are located (http://localhost:10870/App).
Compile and point your browser at http://localhost:10870/App/GetSoftwareVersion. You should see the result on screen.
Refs: