Nathaniel Elkins
Nathaniel Elkins

Reputation: 729

ProtocolException Unhandled/(405) Method not allowed with WCF; Bindings and Endpoints look right though

I'm just learning how to use WCF and I am trying to write a little HelloWorld program from scratch (both the host and client sides). I've been getting a ProtocolException Unhandled whenever my client tries to use the service, and I can't figure out why. I'm hosting the service using IIS.

Regarding the way I have things set up: I'm doing my best to separate the client, proxy, host, service, and contract as detailed in this video and as outlined in this article. Basically I've got different projects within the solution for each of those.

Here are some different files showing what I'm talking about:

Service

namespace HelloWorld
{
  public class HelloWorldService : IHelloWorldService
  {
    public String GetMessage(String name)
    {
        return "Hello World from " + name + "!";
    }
  }
}

Contract

namespace HelloWorld
{
  [ServiceContract]
  public interface IHelloWorldService
  {
      [OperationContract]
      String GetMessage(String name);
  }
}

Proxy

namespace HelloWorld
{
  public class Proxy : ClientBase<IHelloWorldService>, IHelloWorldService
  {
    #region IHelloWorldService Members

    public String GetMessage(String name)
    {
        return Channel.GetMessage(name);
    }

    #endregion

  }

}

Client

namespace Client
{
  public partial class Form1 : Form
  {
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click_1(object sender, EventArgs e)
    {
        Proxy proxy = new Proxy();
        MessageBox.Show(proxy.GetMessage(textBox1.Text));
    }
  }

}

The client is just a form with a textbox and a button, and it tries to execute GetMessage() using whatever is in the textbox as a parameter. There is another class that actually creates an instance of the form.

Here's my web.config for the website:

Web.config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyServiceTypeBehaviors">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior> 
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="HelloWorld.HelloWorldService" behaviorConfiguration="MyServiceTypeBehaviors">
        <endpoint address="http://localhost:8002/" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService"/>
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>

And here's my app.config that goes with the client:

app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <client>
      <endpoint address="http://localhost:8002/" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService" />
    </client>
  </system.serviceModel>

</configuration>

My svc file is very short, just:

HelloWorldService.svc

<%@ServiceHost Service="HelloWorld.HelloWorldService"%>

I know the service is running, because when I navigate to http://localhost:8002/HelloWorldService.svc in my browser I get the screen that says

You have created a service.

To test this service, you will need to create a client and use it to call the service.

So here's where the snag happens: the service is running using IIS, I start an instance of the client, the window with the textbox and the button come up, I type in some letters, hit the button, and then the program crashes and I get the ProtocolException Unhandled, (405) Method not allowed. The error happens on this line of the Proxy class:

return Channel.GetMessage(name);

I've been trying to figure this out for hours and hours, and I haven't made much progress. If someone could at least point me in the right direction, I would be very appreciative.

Last thing: I want to write the client and proxy from scratch, without using svcutil.exe.

Upvotes: 40

Views: 48353

Answers (5)

Avinash Gawali
Avinash Gawali

Reputation: 11

Enabling below two components, worked for me.

enter image description here

Upvotes: 1

Manish Anjara
Manish Anjara

Reputation: 51

You have to specify full address for your service in the endpoint tag of Client configuration

address="http://localhost:8002/HelloWorldService.svc", where you put same endpoint configurations.

It did work for me while I trapped in hell...

Upvotes: 3

Rashmi Singh
Rashmi Singh

Reputation: 87

You have to specify full address for your service in the endpoint tag of Client configuration. Like this:

<endpoint address="http://localhost:8002/HelloWorldService.svc" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService" />

Do not forget to add '.svc' extension after your service name in address attribute of endpoint tag. It worked for me. Hope you will get the solution now.

Client config will look like this:

 <system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_IService"/>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:61569/Service1.svc" binding="wsHttpBinding" 
            bindingConfiguration="WSHttpBinding_IService" contract="WcfServiceApp.IService1" name="WSHttpBinding_IService"/>
</client>

Upvotes: 6

Nathaniel Elkins
Nathaniel Elkins

Reputation: 729

Ok, found a solution, although I'm not entirely sure why it works. I guess when you are using Cassini or IIS or whatever to host the website, you're not supposed to specify an address in the endpoint in the web.config file. All I had to do was change it to address="" and it started working properly. Be sure to make sure the port your server is hosting the service on matches the code in your app.config file.

Upvotes: 2

Rick Rainey
Rick Rainey

Reputation: 11256

The reason it works when you go to the base address (.svc) is that this is an HTTP GET operation to get the metadata for the service. When you call a method on your service contract, you're doing a POST operation and more than likely you just don't have this feature enabled. Depending on the .NET version you're targeting, it will be one of these highlighted in red.

enter image description here

Upvotes: 103

Related Questions