在没有客户端或代理的情况下调用 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 的期望。所有 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);
}