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...
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.
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>
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)
User contributions licensed under CC BY-SA 3.0