C# ProtocolException Unhandled/(405) WCF 不允许方法;绑定和端点看起来不错
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18004206/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ProtocolException Unhandled/(405) Method not allowed with WCF; Bindings and Endpoints look right though
提问by Nathaniel Elkins
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.
我只是在学习如何使用 WCF,我正在尝试从头开始编写一个小小的 HelloWorld 程序(主机和客户端)。ProtocolException Unhandled
每当我的客户尝试使用该服务时,我都会收到一个,但我不知道为什么。我正在使用 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 videoand 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.
客户端只是一个带有文本框和按钮的表单,它尝试使用文本框中的任何内容作为参数来执行 GetMessage()。还有另一个类实际上创建了表单的一个实例。
Here's my web.config for the website:
这是我的网站 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>
And here's my app.config that goes with the client:
这是我与客户端一起使用的 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>
My svc file is very short, just:
我的 svc 文件很短,只是:
HelloWorldService.svc
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
我知道该服务正在运行,因为当我http://localhost:8002/HelloWorldService.svc
在浏览器中导航时,我看到的屏幕显示
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:
所以这里是障碍发生的地方:服务正在使用 IIS 运行,我启动了一个客户端实例,带有文本框和按钮的窗口出现,我输入一些字母,点击按钮,然后程序崩溃,我得到ProtocolException Unhandled, (405) Method not allowed.
错误发生在Proxy类的这一行:
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.
最后一件事:我想从头开始编写客户端和代理,而不使用 svcutil.exe。
采纳答案by Nathaniel Elkins
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.
好的,找到了一个解决方案,虽然我不完全确定它为什么有效。我猜当您使用 Cassini 或 IIS 或其他任何东西来托管网站时,您不应该在 web.config 文件的端点中指定地址。我所要做的就是将其更改为address=""
并开始正常工作。请务必确保您的服务器托管服务的端口与您的 app.config 文件中的代码相匹配。
回答by Rick Rainey
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.
当您转到基地址 (.svc) 时它起作用的原因是这是一个 HTTP GET 操作来获取服务的元数据。当您调用服务合同上的方法时,您正在执行 POST 操作,而且很可能只是没有启用此功能。根据您所针对的 .NET 版本,它将是其中一个以红色突出显示的版本。
回答by Rashmi Singh
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.
不要忘记在端点标记的地址属性中的服务名称后添加“.svc”扩展名。它对我有用。希望你现在能得到解决方案。
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>
回答by Manish Anjara
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.
address="http://localhost:8002/HelloWorldService.svc",您可以在其中放置相同的端点配置。
It did work for me while I trapped in hell...
当我被困在地狱中时,它确实对我有用......