使 WCF Web 服务与 GET 请求一起工作
Posted
技术标签:
【中文标题】使 WCF Web 服务与 GET 请求一起工作【英文标题】:Making a WCF Web Service work with GET requests 【发布时间】:2010-10-30 23:44:26 【问题描述】:背景
我过去创建了 ASMX Web 服务,并且能够从 Web 浏览器和使用地址约定的 Ajax GET 请求访问该服务:MyService.asmx/MyMethod?Param=xxx
我刚刚开始使用 WCF,并在我的 ASP.NET 项目中创建了一个新的 Web 服务。它会创建一个扩展名为 .svc 的文件,例如 MyService.svc。
现状
我可以使用 VS2008 附带的WcfTestClient
来使用该服务。我还可以通过在另一个项目中添加服务引用或使用svcutil.exe
命令行生成代理和配置文件来创建自己的 WCF 客户端。
问题
当我尝试使用 MyService.svc/MyMethod?MyParam=xxx
从浏览器中使用该服务时,我得到一个没有任何错误的空白页面。
我的尝试
我已经在 web.config 中添加了 basicHttpBinding 并在行为配置中设置为 HttpGetEnabled。我还在运营合同中添加了[WebGet(UriTemplate = "MyMethod?MyParam=MyParam")]
属性。
我已经关注了另一个堆栈溢出问题中的信息:REST / SOAP EndPoints for a WCF Service
但是,执行这些步骤后,我要么得到一个空白页面,要么得到一个 HTTP 404 错误。代码没有什么特别之处。我只是将一个字符串作为参数并返回“Hello xxx”。这是一个基本的“Hello WCF World”概念验证类型的东西。
UPDATE - 这是相关代码
[ServiceContract]
public interface IMyService
[WebGet(UriTemplate = "MyMethod/MyParam=MyParam")]
[OperationContract]
string MyMethod(string MyParam);
Web.Config - system.serviceModel 部分
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyService">
<endpoint address=""
binding="wsHttpBinding" contract="IMyService" />
<endpoint address="MyService.svc"
binding="basicHttpBinding" contract="IMyService" />
<endpoint address="mex"
binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
【问题讨论】:
【参考方案1】:查看您的web.config
serviceModel 部分,我可以看到您需要添加一个webHttpBinding 并关联一个包含webHttpGet 的endPointBehavior。
您的运营合同是正确的。下面是您的 system.serviceModel 配置部分的外观,以便您能够从 GET HTTP 请求中使用服务。
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyServiceBehavior" name="MyService">
<endpoint address="ws" binding="wsHttpBinding" contract="IMyService"/>
<endpoint address="" behaviorConfiguration="WebBehavior"
binding="webHttpBinding"
contract="IMyService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
请务必为您的 wsHttpBinding 端点分配不同的地址,否则您将收到错误消息,指出您有两个端点正在侦听同一个 URI。
另一种选择是将 wsHttpBinding 中的地址留空,但为 webHttpBinding 服务分配不同的地址。但是,这也会改变您的 GET 地址。
例如,如果您将地址分配为“asmx”,您将使用地址“MyService.svc/asmx/MyMethod?MyParam=xxxx
”调用您的服务。
【讨论】:
我想我需要的只是添加 endPointBehavior。它就像一个魅力。谢谢。【参考方案2】:正常的 WCF 请求始终是 SOAP 请求 - 仅使用浏览器无法实现这一点,您需要 WCF 测试客户端。
有一个名为 WCF REST Starter Kit 的 WCF 附加组件(也将包含在带有 .NET 4.0 的 WCF 4.0 中),它允许您使用 GET/POST/PUT/DELETE HTTP 命令来查询 WCF 服务和这样的。但是,您需要专门为 REST 编写服务 - 您不能在同一个服务调用中使用 SOAP 和 REST。
马克
【讨论】:
【参考方案3】:作为marc_s says,REST Starter Kit 可以提供帮助,但您也应该知道 .NET 3.5 直接在其中支持 REST 服务。它不像您可以使用入门工具包完成的那样完整,但它很有用。
它的工作方式是在操作中添加[WebGet]
属性,以指示各种参数应来自 URL 中的哪个位置:
[WebGet(UriTemplate = "helloworld/name")]
string Helloworld(string name);
请参阅this portal 了解大量信息。
注意,如果您在配置中指定多个端点/绑定,则可以将相同的服务同时公开为 SOAP 和 REST。
【讨论】:
正如我在问题中提到的那样,我的操作合同中确实有 WebGet 属性。我错过了我的问题中的 UriTemplate 部分,但这就是我在代码中的方式。你自己试过吗? 是的,这就是我们构建 REST 服务的方式。 @Erv - 我编辑了我的问题并发布了我的 web.config 的 ServiceContract 和 serviceModel 部分的内容。你能看看我是否遗漏了什么。正如我之前所说,这在 WcfClient 中可以正常工作,而不是来自 GET 请求。 REST 需要的绑定是 webHttpBinding。您在 Web 配置中的绑定都是 SOAP(即不是 GET 请求)。以上是关于使 WCF Web 服务与 GET 请求一起工作的主要内容,如果未能解决你的问题,请参考以下文章
如何使 Windows 商店应用程序与 TLS 1.2 一起使用?
JsonWriter POST 在 Android 中无法工作到 WCF Web 服务