1

我的服务合同如下:

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

4

2 回答 2

2

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

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

现在,如果你对服务合同有权力,你可以考虑在你的网络服务中实现 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 可以让你做更多的事情(比如提供参数,或者修改数据等),所有这些都使用简单的 url。有关 WCF RESTful api 的教程,请参阅. 或者搜索 MSDN。

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

于 2013-10-14T23:43:33.050 回答
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);
}
于 2013-10-14T23:49:26.767 回答