ProtocolException未处理/(405)WCF不允许的方法; 绑定和端点看起来正确

Nat*_*ins 26 .net c# iis wcf

我正在学习如何使用WCF,我正在尝试从头开始编写一个小的HelloWorld程序(主机和客户端).ProtocolException Unhandled每当我的客户尝试使用该服务时,我都会得到一个,我无法弄明白为什么.我正在使用IIS托管服务.

关于我设置的方式:我正在尽力分离客户端,代理,主机,服务和合同,详见本视频本文所述.基本上我在解决方案中为每个项目提供了不同的项目.

这里有一些不同的文件显示我在说什么:

服务

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

合同

namespace HelloWorld
{
  [ServiceContract]
  public interface IHelloWorldService
  {
      [OperationContract]
      String GetMessage(String name);
  }
}
Run Code Online (Sandbox Code Playgroud)

代理

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

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

    #endregion

  }
Run Code Online (Sandbox Code Playgroud)

}

客户

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));
    }
  }
Run Code Online (Sandbox Code Playgroud)

}

客户端只是一个带有文本框和按钮的表单,它尝试使用文本框中的任何内容作为参数来执行GetMessage().还有另一个类实际上创建了表单的实例.

这是我的网站web.config:

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>
Run Code Online (Sandbox Code Playgroud)

这是我的app.config与客户端:

的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>
Run Code Online (Sandbox Code Playgroud)

我的svc文件很短,只是:

HelloWorldService.svc

<%@ServiceHost Service="HelloWorld.HelloWorldService"%>
Run Code Online (Sandbox Code Playgroud)

我知道该服务正在运行,因为当我http://localhost:8002/HelloWorldService.svc在浏览器中导航时,我会看到屏幕上显示的内容

您已创建了一项服务.

要测试此服务,您需要创建一个客户端并使用它来调用该服务.

所以这里发生了障碍:服务正在使用IIS运行,我启动客户端实例,带文本框和按钮的窗口出现,我输入一些字母,点击按钮,然后程序崩溃,我得到ProtocolException Unhandled, (405) Method not allowed. 错误发生在Proxy类的这一行:

return Channel.GetMessage(name);
Run Code Online (Sandbox Code Playgroud)

我一直试图解决这个问题几个小时,我没有取得多大进展.如果有人能够至少指出我正确的方向,我将非常感激.

最后一件事:我想从头开始编写客户端和代理,而不使用svcutil.exe.

Ric*_*ney 75

当你转到基地址(.svc)时它工作的原因是这是一个HTTP GET操作来获取服务的元数据.当您在服务合同上调用方法时,您正在进行POST操作,而且很可能您没有启用此功能.根据您要定位的.NET版本,将以红色突出显示其中一个.

在此输入图像描述

  • 当我导航到Windows功能时,已经选中了.NET Framework 3.5及其子文件夹的选项.没有.NET Framework 4.5 Advanced Services的文件夹.这很奇怪,因为它安装在计算机上(如果我导航到可以卸载程序的菜单,我会看到Microsoft .NET Framework,Microsoft .NET Framework多目标包和Microsoft .NET Framework SDK).知道为什么这些选项可能没有显示出来吗? (4认同)
  • 这节省了我的一天! (2认同)
  • 谢谢你。也许我只是不太了解 Windows 或 IIS,但这些 Windows 功能设置似乎如此随意、隐藏和不必要。 (2认同)

Ras*_*ngh 5

您必须在“客户端配置”的端点标记中指定服务的完整地址。像这样:

<endpoint address="http://localhost:8002/HelloWorldService.svc" binding="basicHttpBinding" contract="HelloWorld.IHelloWorldService" />
Run Code Online (Sandbox Code Playgroud)

不要忘记在端点标记的address属性中的服务名称之后添加“ .svc”扩展名。它为我工作。希望您现在能得到解决方案。

客户端配置将如下所示:

 <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>
Run Code Online (Sandbox Code Playgroud)


Nat*_*ins 2

好吧,找到了一个解决方案,尽管我不完全确定它为什么有效。我想当您使用 Cassini 或 IIS 或其他任何东西来托管网站时,您不应该在 web.config 文件中的端点中指定地址。我所要做的就是将其更改为address="",它就开始正常工作了。请务必确保服务器托管服务的端口与 app.config 文件中的代码匹配。