Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
237 views
in Technique[技术] by (71.8m points)

c# - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...