79

背景:

我正在创建一个 Web 服务站点,它将通过 SOAP 和可能的其他协议提供多种类型的简单服务。目标是让转换、RSS 解析、垃圾邮件检查和许多其他类型的工作变得容易。该网站将主要针对初学者开发人员。

我的问题:

我从未为此开发过任何 C# 或 .NET。多年前我确实破解了一些 VB6,但仅此而已。现在我需要一些在 C# 中通过 SOAP 进行 RPC 调用的示例。我试图搜索网络和 Stack Overflow 来找到这个,但没有找到很多资源,我不知道如何对资源进行排名(哪些是旧的?哪些是不正确的?等等)。

我创建了一个简单的示例服务,在 PHP 中这样调用:

<?php
$client = new SoapClient('http://webservi.se/year'); //URL to the WSDL
echo $client->getCurrentYear(); //This method returns an integer, called "year"
?>

我现在想在 C# 中尽可能轻松地调用此方法。非常欢迎所有参考资料和示例。我从哪里开始?我可以使用哪些类/模块/什么?

如果有更好的通信框架(后端是可扩展的),该解决方案根本不必涉及 SOAP,但请注意,服务器端是在 Unix 上用 PHP 实现的,因此微软的专有解决方案是不可能的服务器端。

请注意,我需要这个,所以我可以为 J. Random Web Developer 编写可能的文档(即使他们在共享网络托管上)。因此,我认为最好的方法应该是仅在代码中执行此操作,但当然也欢迎其他方式执行此操作。

4

6 回答 6

155

先决条件:您已经拥有服务和已发布的 WSDL 文件,并且您想从 C# 客户端应用程序调用您的 Web 服务。

有两种主要方法可以做到这一点:

A) ASP.NET 服务,这是执行 SOA 的旧方式
B) WCF,正如 John 所建议的,它是 MS 的最新框架,并提供许多协议,包括开放和 MS 专有协议。

逐步添加服务引用

最简单的方法是在 C# 应用程序中生成代理类(这个过程称为添加服务引用)。

  1. 在 Visual Studio 中打开您的项目(或创建一个新项目)
  2. 在解决方案资源管理器中右键单击项目(在项目而不是解决方案上),然后单击添加服务引用
  3. 下面的屏幕截图中应显示一个对话框。输入 wsdl 文件的 url,然后点击 Ok。请注意,如果您在点击 ok 后收到错误消息,请尝试从 url 中删除 ?wsdl 部分。

    添加服务参考对话框

    我以http://www.dneonline.com/calculator.asmx?WSDL为例

  4. 在解决方案资源管理器中展开服务引用并双击CalculatorServiceReference(或在上一步中命名服务的任何名称)。

    您应该会看到生成的代理类名称和命名空间。

    在我的例子中,命名空间是SoapClient.CalculatorServiceReference,代理类的名称是CalculatorSoapClient。正如我上面所说,类名可能因您的情况而异。

    服务引用代理类

  5. 转到您的 C# 源代码并添加以下内容

    using WindowsFormsApplication1.ServiceReference1
    
  6. 现在您可以通过这种方式调用服务。

    Service1Client service = new Service1Client();
    int year = service.getCurrentYear();
    

希望这可以帮助。如果您遇到任何问题,请告诉我们。

于 2011-07-09T11:21:33.683 回答
25

我已经做了很多你所说的事情,平台之间的 SOAP 互操作性有一个基本规则:合同第一。不要代码派生 WSDL,然后尝试在不同平台上生成客户端。除了“Hello World”类型的函数之外的任何东西都很可能无法生成代码、无法在运行时交谈或(我最喜欢的)无法正确发送或接收所有数据而不会引发错误。

也就是说,WSDL 是复杂的、讨厌的东西,我尽可能避免从头开始编写它。以下是一些可靠的服务互操作指南(使用 Web 引用、WCF、Axis2/Java、WS02、Ruby、Python 等等):

  • 继续执行代码优先来创建您的初始 WSDL。然后,删除您的代码并从 WSDL 重新生成服务器类。几乎每个平台都有用于此目的的工具。这将向您展示您的特定平台有哪些奇怪的习惯,并且您可以开始调整 WSDL 以使其更简单、更直接。调整,重新生成,重复。通过这种方式你会学到很多东西,而且它是可移植的知识。
  • 对于复杂类型,坚持使用简单的旧语言类(POCO、POJO 等)。不要使用特定于平台的结构,如 List<> 或 DataTable。即使是 PHP 关联数组也似乎可以工作,但会以难以跨平台调试的方式失败。
  • 坚持使用基本数据类型:bool、int、float、string、date(Time) 和数组。奇怪的是,您对数据类型的了解越具体,随着时间的推移,您对新需求的敏捷性就越低。如果可以避免,您不想更改 WSDL。
  • 上述数据类型的一个例外 - 给自己一种 NameValuePair 机制。你不会相信这些东西的清单多少次会在灵活性方面节省你的培根。
  • 为您的 WSDL 设置一个真正的名称空间。这并不难,但你可能不相信我在命名空间“http://www.tempuri.org”中看到了多少 Web 服务。此外,使用 URN(“urn:com-myweb-servicename-v1”,而不是基于 URL 的命名空间(“http://servicename.myweb.com/v1”。它不是网站,它是一组抽象字符这定义了一个逻辑分组。我可能有十几个人打电话给我寻求支持,说他们去了“网站”,但没有用。

</rant>:)

于 2011-07-14T02:40:15.153 回答
7

看看“将 WCF 服务与 PHP 结合使用”。它解释了您需要的基础知识。

作为理论总结:

WCF 或 Windows Communication Foundation 是一种允许定义从方式抽象的服务的技术 - 底层通信方法 - 它们将被调用。

这个想法是你定义一个关于服务做什么和服务提供什么的契约,并定义另一个关于使用哪种通信方法来实际使用服务的契约,无论是 TCP、HTTP 还是 SOAP。

你有文章的第一部分在这里,解释如何创建一个非常基本的 WCF 服务。

更多资源:

将 WCF 与 PHP5 一起使用

另外看看 NuSOAP。如果您现在使用 NuSphere,这是一个工具包,可让您从 PHP 连接到 WCF 服务。

于 2011-07-09T11:37:38.183 回答
7

如果您可以让它在浏览器中运行,那么像这样简单的东西就可以了

var webRequest = WebRequest.Create(@"http://webservi.se/year/getCurrentYear");

using (var response = webRequest.GetResponse())
{
    using (var rd = new StreamReader(response.GetResponseStream()))
    {
        var soapResult = rd.ReadToEnd();
    }
}
于 2011-07-14T20:33:44.980 回答
6

你找错地方了。您应该查找Windows Communication Framework


WCF 在客户端和服务器上都使用。

于 2010-06-23T10:05:50.183 回答
5

在这里,您可以找到一个很好的教程,用于从 .NET 客户端应用程序调用基于 NuSOAP 的 Web 服务。但是 IMO,您还应该考虑使用WSO2 Web Services Framework for PHP (WSO2 WSF/PHP)进行服务。请参阅PHP 2.0 的 WSO2 Web 服务框架显着增强了业界唯一用于创建 SOAP 和 REST 服务的 PHP 库。还有一个关于它的网络研讨会。

现在,在 .NET 世界中,考虑到互操作性问题,我也鼓励使用 WCF。可以在此处找到互操作性示例,但此示例使用 PHP 客户端 + WCF 服务,而不是相反。随意实现 PHP 服务和 WFC 客户端。

在 codeplex.com 上有一些 WCF 的相关开源项目,我发现它们非常有成效。这些项目对于设计和实现 Win Forms 和 Windows Presentation Foundation 应用程序非常有用:Smart ClientWeb ClientMobile Client。它们可以与 WCF 结合使用,以明智地调用任何类型的 Web 服务。

一般来说,模式和实践团队总结了各种处理 .NET 平台,特别是 web 的开源项目中的良好实践和设计。因此,我认为这是任何与 .NET 客户端相关的设计决策的良好起点。

于 2011-07-11T20:59:42.130 回答