I am a newbie at WCF. I created a WCF restful service in VS2010 (WCF service appl). It was targeted for Framework 4.0. I hosted this service on local IIS with appl pool set for framework 4.0. When I call the appl methods from browser or fiddler, they work fine. Now, I created a client console based. When I call any method from client I get the following Communication Exception:
** remote server returned an unexpected response: (405) Method Not Allowed.**
Service Interface file:
namespace MyService
{
[ServiceContract]
public interface ITestService
{
[WebGet(UriTemplate = "GetDateTime")]
[OperationContract]
string GetDateTime();
[WebGet(UriTemplate = "GetName")]
[OperationContract]
string GetName();
}
}
Class that implements the above interface:
namespace MyService
{
public class TestService : ITestService
{
public string GetDateTime()
{
return DateTime.Now.ToString();
}
public string GetName()
{
return "MY name is KingKong";
}
}
}
Web.config file:
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyService.TestService">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="" contract="MyService.ITestService">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
TestService.svc
<%@ ServiceHost Language="C#" Debug="true" Service="MyService.TestService" CodeBehind="TestService.svc.cs" %>
Client app.config:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://localhost/BestService/TestService.svc"
binding="webHttpBinding" bindingConfiguration="" contract="MyService.ITestService"
name="MyClientConfig" kind="" endpointConfiguration="" />
</client>
</system.serviceModel>
Client program calling proxy class
static void Main(string[] args)
{
TestServiceClient proxy = null;
try
{
proxy = new TestServiceClient();
Console.WriteLine("Test 1: List all products");
string sdatetime = proxy.GetName();
Console.WriteLine("Datetime: {0}", sdatetime);
Console.WriteLine();
// Disconnect from the service
proxy.Close();
}
catch (CommunicationException cex)
{
if (cex.InnerException != null)
{
Console.WriteLine("{0}", cex.InnerException.Message);
}
else
{
Console.WriteLine("General exception: {0}", cex.Message);
}
}
catch (Exception e)
{
if (e.InnerException != null)
{
Console.WriteLine("{0}", e.InnerException.Message);
}
else
{
Console.WriteLine("General exception: {0}", e.Message);
}
}
Console.WriteLine("Press ENTER to finish");
Console.ReadLine();
}
I added a service reference to the application and the Reference.cs file has following partial code:
namespace MyClient.MyService {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(ConfigurationName="MyService.ITestService")]
public interface ITestService {
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITestService/GetDateTime", ReplyAction="http://tempuri.org/ITestService/GetDateTimeResponse")]
string GetDateTime();
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/ITestService/GetName", ReplyAction="http://tempuri.org/ITestService/GetNameResponse")]
string GetName();
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public interface ITestServiceChannel : MyClient.MyService.ITestService, System.ServiceModel.IClientChannel {
}
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class TestServiceClient : System.ServiceModel.ClientBase<MyClient.MyService.ITestService>, MyClient.MyService.ITestService {
public TestServiceClient() {
}
public TestServiceClient(string endpointConfigurationName) :
base(endpointConfigurationName) {
}
public TestServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public TestServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {
}
public TestServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
public string GetDateTime() {
return base.Channel.GetDateTime();
}
public string GetName() {
return base.Channel.GetName();
}
}
}
Please help me as I have spent nearly 2 days trying to figure out the problem in the client
Thanks
VS2010 doesnt have the ability to generate a proxy for a RESTFUL service as it does for a SOAP based service. So the solution is write your own proxy class which inherits from the ClientBase class and use the Channel to call the web methods of the service.