在没有客户端或代理的情况下调用WCF服务

时间:2013-10-14 23:13:54

标签: c# wcf webrequest

我有如下服务合同:

[ServiceContract]
public interface IWebProxyService
{
    [OperationContract]
    string GetSomeData();
}

我也在合约上试过这个属性。

[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetFormsBaseUrl")] 

是否可以在没有任何服务引用/合同的情况下从另一个应用程序调用它。

我尝试了以下一系列变体(来自app):

 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方法?

2 个答案:

答案 0 :(得分:2)

您将无法像在代码中那样执行此操作并获得类似的响应。 “错误请求”只是WCF告诉您,您的请求不符合WCF的预期。所有WCF调用都希望消息采用SOAP格式,否则服务器将无法识别您的呼叫。想象一下,如果您的服务合同有两种方法而不是一次,那么当您发送这样的请求时,WCF如何知道要调用哪一种?答案是,当您使用客户端代理(由工具生成或使用ChannelFactory自己创建)调用WCF时,请求将封装到SOAP消息中,该消息包含更多信息以允许WCF识别要调用的端点,调用什么方法,以及提供的参数。

如果你确实想避免使用客户端代理类(你没有说明原因,所以我假设你有一个好的),理论上,你可以自己构造SOAP消息,并嵌入到http头中并发送http web请求。但是,这显然不是我推荐的方法。

现在,如果你掌握了服务合同,你可以考虑在你的网络服务中实施RESTful api,它允许你使用普通的http网址“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的教程,请参阅this。或者搜索MSDN。

编辑:您甚至不需要编写代码来验证restful api的工作原理,您可以启动Web浏览器并查看服务器的响应,这非常适合测试。

答案 1 :(得分:0)

以下不是答案,只是一个发表评论。我希望它能保持足够长的时间让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);
}