I have a RESTful WCF web service with the following API:
[WebGet(ResponseFormat = WebMessageFormat.Json)]
MyResponseContract GetFileInfo();
When attempting to hit endpoint (using SOAPUI) I see the following error message:
The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service.
I have SOAPUI set to hit it with a GET method call. When I switch it to a POST with no body, it fails with the following message:
Method not allowed.
This makes perfect sense: can't hit a GET with a POST. So I updated my code as follows:
[WebInvoke(ResponseFormat = WebMessageFormat.Json)]
MyResponseContract GetFileInfo();
And now I call it from SOAPUI with a POST method and it works. Curious. So I now change my code as follows:
[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "GET")]
MyResponseContract GetFileInfo();
I've seen in a few posts that this is essentially equivalent to a WebGet
attribute. This also does not work.
So my question is: why doesn't this work as a WebGet
even though I am not accepting parameters or using a custom UriTemplate?
The Url I'm trying to hit it with (it's hosted locally in IIS) is:
http://localhost/Utilities/API/GetFileInfo
Update Given the comments below and the given answers, I am still faced with this problem. Some additional details.
My web-layer web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="10000000" />
</webHttpEndpoint>
</standardEndpoints>
<behaviors>
<endpointBehaviors>
<behavior name="exampleBehavior">
<callbackDebug includeExceptionDetailInFaults="true" />
<enableWebScript />
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" maxReceivedMessageSize="10000000" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://LOCALHOST/Utilities.AppService/API"
binding="webHttpBinding" bindingConfiguration="WebHttpBinding"
contract="Utilities.Common.API.IMyApi"
behaviorConfiguration="exampleBehavior" />
</client>
</system.serviceModel>
</configuration>
My app-layer web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<customErrors mode="Off" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxReceivedMessageSize="10000000" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</configuration>
My service interface
[ServiceContract(Namespace = "API")]
public interface IMyApi
{
[WebGet]
MyResponseContract GetFileInfo();
}
My web-layer implementation
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyApiWebService : ClientBase<IMyApi>, IMyApi
{
public MyResponseContract GetFileInfo()
{
return Channel.GetFileInfo();
}
}
My app-layer implementation
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MyApiAppService : IMyApi
{
public MyResponseContract GetFileInfo()
{
return new MyResponseContract();
}
}
My web-layer Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("API", new WebServiceHostFactory(), typeof(MyApiWebService)));
}
My app-layer Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("API", new WebServiceHostFactory(), typeof(MyApiAppService)));
}
I'm not sure how much more detail I can provide. As you can see, given the solutions provided, I have implemented everything suggested to no avail. Whether I am trying to hit this WebGet
method by placing the web layer service url in the browser, or using SOAPUI, or trying to hit it with a C# unit test using a service client, I am unable to use WebGet
. Thanks again for all of your help.
And interesting note is that the App-layer URL works. But the web layer does not. So:
localhost/Utilities.AppService/API/GetFileInfo
works, whereas
localhost/Utilities.WebService/API/GetFileInfo
does not.
WebHttpBinding
? – FortuitywebHttpBinding
. – Starveling