在没有客户端或代理的情况下调用 WCF 服务
本文关键字:情况下 调用 WCF 服务 代理 客户端 | 更新日期: 2023-09-27 18:35:15
我有一个服务合同如下:
[ServiceContract]
public interface IWebProxyService
{
[OperationContract]
string GetSomeData();
}
我也在合同上尝试了这个属性。
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetFormsBaseUrl")]
是否可以在没有任何服务引用/协定的情况下从另一个应用程序调用它。
我已经尝试了以下一堆变体(来自调用应用程序):
public static void GetSomeData(string webServiceProxyURL)
{
WebRequest request = WebRequest.Create(webServiceProxyURL);
request.Method = "GET";
request.ContentType = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
Console.WriteLine("Response: 'n" + responseFromServer);
}
我收到"远程服务器返回错误:(400) 错误请求"。Web 异常状态为"System.Net.WebExceptionStatus.ProtocolError"我做错了什么,如何从其他应用程序调用 WCF 方法?
你将无法像在代码中那样做到这一点并获得这样的响应。"错误请求"只是 WCF 告诉您您的请求不符合 WCF 的期望。所有 WCF 调用都要求消息采用 SOAP 格式,否则服务器将无法识别您的调用。想象一下,如果您的服务协定有两个方法,而不仅仅是一个,那么当您发送这样的请求时,WCF 如何知道要调用哪一种方法?答案是,当您使用客户端代理(由工具生成或由您使用 ChannelFactory 自行创建)调用 WCF 时,请求将封装到 SOAP 消息中,该消息包含更多信息,以允许 WCF 确定要调用的终结点、要调用的方法以及提供的参数。
如果你确实想避免使用客户端代理类(你没有说原因,所以我假设你有一个很好的代理类),理论上你可以自己构造 SOAP 消息,并嵌入到 http 标头中并与 http web 请求一起发送。但是,这显然不是我推荐的方法。
现在,如果你对服务合约有权力,你可以考虑在你的 Web 服务中实现 RESTful api,它将允许你使用普通的 http url(如"http://yourserver.com/getdata")访问服务。在大多数情况下,在 WCF 中实现 RESTful 服务非常容易,您只需要在服务协定中添加一个属性!将其更改为类似以下内容(添加属性,仅此而已)
[ServiceContract]
public interface IWebProxyService
{
[OperationContract]
[WebGet(UriTemplate="getData")]
string GetSomeData();
}
然后将服务配置为使用 webHttpBinding,如下所示:
<configuration>
<system.serviceModel>
<services>
<service name="...">
<endpoint binding="webHttpBinding" contract="..."
behaviorConfiguration="webHttp"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<configuration>
然后从客户端,你可以不使用服务合约访问 Web 服务,只需普通的 WebRequest;您需要将"/getData"附加到服务 uri 的末尾,并且响应采用 xml 格式。
RESTful api 可以让你做更多的事情(比如提供参数,或修改数据等),所有这些都使用简单的 url。有关 WCF RESTful API 的教程,请参阅此处。或者搜索 MSDN。
编辑:您甚至不需要编写代码来验证 restful api 是否正常工作,您只需启动您的 Web 浏览器并查看来自服务器的响应,这对于测试非常有用。
以下不是答案,只是一个胖评论。我希望它停留的时间足够长,以便 OP 阅读它。
代码的一个大问题是你没有正确处理IDisposable
对象。这将导致资源泄漏。请尝试以下操作:
public static void GetSomeData(string webServiceProxyURL)
{
var request = WebRequest.Create(webServiceProxyURL);
request.Method = "GET";
request.ContentType = "application/json";
string responseFromServer = "No response from server";
using (var response = (HttpWebResponse) request.GetResponse())
{
using (var dataStream = response.GetResponseStream())
{
if (dataStream != null)
{
using (var reader = new StreamReader(dataStream))
{
responseFromServer = reader.ReadToEnd();
}
}
}
}
Console.WriteLine("Response: 'n" + responseFromServer);
}