Hosting REST webservice on WCF with IIS

1

Here's my simplified example:

web.config:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <services>
      <service name="Services.DBService">
        <endpoint address="http://localhost/" binding="webHttpBinding"
          contract="Contracts.IDBService" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="">
          <webHttp defaultOutgoingResponseFormat="Json" />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

Supported by the following contract:

using System.ServiceModel;

namespace Contracts
{
    [ServiceContract]
    public interface IDBService
    {
        [OperationContract]
        Services.Person GetData(string id);
    }

}

and service:

using System.ServiceModel.Web;

namespace Services
{
    public class DBService : Contracts.IDBService
    {
        [WebInvoke(Method = "GET", UriTemplate = "data/{id}")]
        public Person GetData(string id)
        {
            return new Person()
            {
                Id = int.Parse(id),
                Name = "John Doe"
            };
        }
    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

Running via IIS Express in the debugger, I can make a GET request to localhost/data/10.

When I try and publish this locally to IIS, however, I get a 404 error when I try to go to localhost/data/10. I'm putting this in the default web application with a root of localhost.

Is there something I need to be aware of using UriTemplate that I don't know about? What am I doing incorrectly?

It's part of an app pool running .NET 4.0, and this app pool is started. Error code:

Module IIS Web Core 
Notification MapRequestHandler 
Handler StaticFile 
Error Code 0x80070002 
Requested URL http://localhost:80/Data/10 
Physical Path C:\inetpub\wwwroot\Data\10 
Logon Method Anonymous 
Logon User Anonymous 

It's trying to find the physical location, and obviously it doesn't exist. How can I configure it to not do this?

Not sure what other info to give, but ask and you will receive...

c#
web-services
wcf
iis
asked on Stack Overflow Oct 15, 2015 by Joseph Nields • edited Oct 15, 2015 by Joseph Nields

3 Answers

1

You need to add some configuration setting in Web.config to define the Route information. So that IIS understand where to redirect the incoming request.

Add following in your web.config:

  <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>

Add reference to System.ServiceModel.Activation library and add Global.asax file in your WCF library project and add below code in Application_Start method.

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

Publish again and you should be good to go.

You can also check out this project for sample of hosting WCF REST service in IIS. Also the library provides custom behavior to support Typed argument in methods which are marked with URI Template.

answered on Stack Overflow Oct 15, 2015 by vendettamit • edited Oct 16, 2015 by vendettamit
1

After looking EVERYWHERE for an answer that actually would work, I found something here.

Basically, you need to mark the services with AspNetCompatibilityRequirementsAttribute like so to enable AspNet compatibility:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class DBService : Contracts.IDBService

and then add a tag to the Web.Config:

<configuration>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>
</configuration>
answered on Stack Overflow Oct 16, 2015 by Joseph Nields
-1

Use [WebGet] attribute for GET requests. See https://msdn.microsoft.com/en-us/library/system.servicemodel.web.webgetattribute.aspx

Should be

[WebGet(UriTemplate = "data/{id}")]
public Person GetData(string id)
answered on Stack Overflow Oct 16, 2015 by Mimas

User contributions licensed under CC BY-SA 3.0