我有如下服务合同:
[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方法?
答案 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);
}