2013-10-14 64 views
0

一个WCF服务,我有一个服务合同如下:没有调用客户端或代理

[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)错误的请求”。网络例外状态是“System.Net.WebExceptionStatus.ProtocolError”我做错了什么,我怎么能从其他应用程序调用WCF方法?

+0

您没有向服务发送任何内容。你能指望什么? –

+0

我想调用返回一个字符串的方法。它没有参数?那么你究竟希望我发送到服务器来调用该方法? –

+0

假设它是一个SOAP Web服务,我希望你发送一个SOAP信封给它。我不知道你的代理类出了什么问题,但作为一个故障排除机制,请尝试使用“添加服务引用”创建一个小客户端应用程序,让它工作,然后检查由工作应用程序发送的XML。然后让你的真实应用发送相同的。 –

回答

1

你不能像你的代码那样做,并得到这样的回复。 '错误的请求'只是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;您需要在服务uri的末尾附加'/ getData',并且响应采用xml格式。

RESTful api可以让你做更多的事情(如提供参数,或修改数据等),所有使用简单的网址。有关WCF RESTful API的教程,请参见this。或搜索MSDN。

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

+0

谢谢@ X.J很好的解释 - 正在工作=) –

+0

@Toby我们如何测试POST请求的restfull WCF服务。我的请求参数是复杂类型的。 –

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); 
} 
相关问题