Hosting a WCF REST service on IIS

Hosting a WCF REST service on IIS

All of the WCF REST samples use self-hosted services and many people have been asking for a sample that is hosted on IIS, so I'll explain how to do that here. Let's start with a simple service contract:

// IService.cs
namespace SimpleRESTService
{
    [ServiceContract]
    public interface IService
    {
        [Description("Simple echo operation over HTTP GET")]
        [WebGet]
        string EchoWithGet(string s);

        [Description("Simple echo operation over HTTP POST")]
        [WebInvoke]
        string EchoWithPost(string s);
    }

 Next, implement the IService contract:

// service1.cs
namespace SimpleRESTService
{
    public class Service1 : IService
    {
        public string EchoWithGet(string s)
        {
            return "You said " + s;
        }

        public string EchoWithPost(string s)
        {
            return "You said " + s;
        }
    }
}

Add the Service1.svc file:

 <%@ ServiceHost Language="C#" Debug="true" Service="SimpleRESTService.Service1" CodeBehind="Service1.svc.cs" %>

And finally add the web.config file:

 <?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="SimpleRESTService.Service1"
                behaviorConfiguration="RESTBehavior">
        <endpoint address=""
                  binding="webHttpBinding"
                  contract="SimpleRESTService.IService"
                   behaviorConfiguration="MyEndpointBehavior"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="RESTBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="MyEndpointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />                             
  </system.serviceModel>
</configuration>

 The easiest way to get this code to run is to create a new WCF Service Application in Visual Studio 2010 (or earlier) and replace the generated files with the files listed here. You can then hit CTRL + F5 and the ASP.NET Development Server will host the WCF app. Don't be confused by the name of the ASP.NET Development Server it can host WCF services. Once the service is hosted you can then use IE to call the operation. Double click on the ASP.NET Development Server icon on the status bar (you may have to click the arrow on the lower right hand side of the status bar to see the icon.) It will display the ASP.NET Development Server dialog which will contain the port number being used by the server.  Then open up IE and type in the following URL: http://localhost%3cport%3e/ where <port> is replaced by the port number found in the ASP.NET Development Server dialog. You should see something like the following:

 Now, the URL we just used isn't very pretty. We'd like to be able to not have to specify the .svc file in the URL. Well, you're in luck the ASP.NET Routing Integration feature allows you to do just that. To use ASP.NET Routing Integration you need to do the following:

1) Turn on ASP.NET compatibility. This is done in the <serviceHostingEnvironment> tag in your web.config file. It can appear anywhere within the <system.ServiceModel> element. Here's an example:

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>

2) Add the UrlRoutingModule and UrlRoutingHandler to your web.config file. These are placed within a <system.webServer> element, which appears outside of the <system.serviceModel> element. Here's an example:

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
   <add name="UrlRoutingModule"
        type="System.Web.Routing.UrlRoutingModule,
          System.Web.Routing, Version=4.0.0.0,
          Culture=neutral,
          PublicKeyToken=31BF3856AD364E35" />

  </modules>
  <handlers>
   <add name="UrlRoutingHandler"
      preCondition="integratedMode"
      verb="*" path="UrlRouting.axd"
      type="System.Web.HttpForbiddenHandler,
         System.Web, Version=4.0.0.0, Culture=neutral,
         PublicKeyToken=b03f5f7f11d50a3a" />
  </handlers>
 </system.webServer>

3) Add a global.asax file to your project by right clicking on the project name in the solution explorer, select Add, New Item... and Global Application Class. Within the Application_Start method, add a Route to the RouteTable that specifies an optional relative path, the WebServiceHostFactory, and the service type. Here's an example:

protected void Application_Start(object sender, EventArgs e)
{
  RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(Service1)));
}

Now you can browse to your service when hosted on the ASP.NET Development Server by using this URL:

 http://localhost%3cport%3e/

So now we have the service hosted under the ASP.NET Development Server, we can use Visual Studio to publish the service to an IIS server. In Visual Studio go to the Build menu and select Publish SampleRESTService. This displays a dialog where you can specify where and how to publish the WCF service:

In the dialog above we specify that we want the service to be hosted in IIS under http://localhost/SimpleRESTService

Make sure the service1.svc file is not in the virtual directory that was created after you click publish. If it is there delete it. Then you can browse to your service by using the following URL:

http://localhost/SimpleRESTService/EchoWithGet?s=Hello

 

 


Other Languages

This article is also available in the following languages:

Brazilian Portuguese (pt-BR)

Sort by: Published Date | Most Recent | Most Useful
Comments
  • Great article.  Is there any way to achieve the same result (a url without the '.svc' extension) in .net 3.5?

  • Thanks for this.

    Feedback:

    The above will throw an exception stating that the WCF should either be marked with AspNetCompatibilityRequirements attribute (enable/require) or set the aspNetCompatibilityEnabled in web.config to false (which is needed for the RouteTable solution above)....

    Doing the former (adding the WCF attribute) will resolve it....so just fyi, and/or further/updated comments....

  • This article was really helpful.

    For those using VB, I have included the transcripts below. Please note that in VB.net you must not set the name space explicitly.

    ' IService1.vb

    Imports System.ComponentModel

    <ServiceContract()>

       Public Interface IService

       <Description("Simple echo operation over HTTP GET")>

       <WebGet()>

       Function EchoWithGet(ByVal s As String) As String

       <Description("Simple echo operation over HTTP POST")>

       <WebInvoke()>

       Function EchoWithPost(ByVal s As String) As String

    End Interface

    ' Service1.svc.vb

    Public Class Service1

       Implements IService

       Public Function EchoWithGet(ByVal s As String) As String Implements IService.EchoWithGet

           Return "You said " + s

       End Function

       Public Function EchoWithPost(ByVal s As String) As String Implements IService.EchoWithPost

           Return "You said " + s

       End Function

    End Class

    ' Service1.svc

    <%@ ServiceHost Language="VB" Debug="true" Service="SimpleRESTService.Service1" CodeBehind="Service1.svc.vb" %>

    Web.config is identical.

    Cheers,

    Thomas Gutzmann

  • Great great article! Very useful !

  • Thanks for sharing.

    I have problem when follow your guidance : I can't write the directive in the svc file.

    There are 3 files in the project:

       IService1.cs

       Service1.svc

       Service1.svc.cs

    I double clicked the Service1.svc but I always get Service1.svc.cs

    I can't find "View Designer" icon which I can write a directive as I found in webform file.

    I build the project using Visual Studio 2008 SP1

    Would you please tell me what mistakes I did?

    Thanks in advance

  • I created the WCF Service application and created and copied code into the files as you suggested.  But when I hit Ctrl+f5  I just see the directory listing of the application in the VS Development Server.  I do not see the xml as you showed.

  • I followed all the way to the end of your article.  After I published the service on to IIS I get End Point not found error in the browser.

  • IMPORTANT: I found out that the Url Routing Module needs "Integrated Mode" it doesn't work in "Classic Mode". Otherwise you'll get the 404 error

Page 1 of 1 (8 items)