C# 中的 Web 服务

2025年3月17日 | 阅读19分钟

引言

Web Service 是一种软件程序。这些服务使用 XML,通过通用的互联网协议与其他软件交换信息。简单来说,我们使用 Web Service 在互联网上与对象进行交互。

以下是关于 Web Service 的一些要点。

  1. Web Service 不依赖于任何特定语言。
  2. Web Service 是协议独立的。
  3. Web Service 是平台无关的。
  4. Web Service 被称为无状态架构。这些服务仅依赖于给定的输入。
  5. Web Service 也是可伸缩的。
  6. Web Service 基于 XML(开放、文本标准)。

Web Service 中使用的技术

XML: Web Service 只指定数据。因此,能够理解 XML 的应用程序,无论其编程语言或平台如何,都可以以不同的方式格式化 XML。

SOAP: 服务与应用程序之间的通信由 SOAP 建立。

WSDL: WSDL 提供了一种统一的方法,有助于将 Web Service 指定给其他程序。

UDDI: 借助 UDDI,我们可以搜索 Web Service 注册表。

在这些技术部署时,它们允许开发人员将应用程序打包成服务,并将服务发布到网络上。

Web Services 的优点

  1. Web Services 始终使用开放的文本标准。Web Service 使用所有这些组件,即使它们是用不同语言为不同平台编写的。
  2. Web Service 促进了模块化编程方法,使多个组织能够与同一个 Web Service 进行通信。
  3. Web Services 易于实现但成本高昂,因为它们利用了现有基础设施,并且我们可以将大部分应用程序重新打包为 Web Service。
  4. Web Service 降低了企业应用程序集成和 B2B 通信的成本。
  5. Web Services 是可互操作的组织,包含 100 家供应商并促进它们之间的互操作性。

Web Services 的局限性

Web Services 的局限性如下:

  1. Web Services 的一个局限性是 SOAP、WSDL、UDDI 需要开发。
  2. 对互操作性的支持也是 Web Service 的一个局限性。
  3. Web Service 的局限性还在于版税。
  4. 如果我们想在高性能场景中使用 Web Service,那么 Web Service 会很慢。
  5. Web Service 的使用会增加网络流量。
  6. Web Services 的安全级别较低。
  7. 我们使用标准程序来描述特定 Web 服务的质量。
  8. Web Service 的标准仍处于草案阶段。
  9. 供应商保留特定标准的知识产权也是 Web Service 的一个局限性。

Web Service 示例

Web Service 几乎可以完成任何类型的任务。

Web Portal: Web Portal 用于从链接的 Web Service 获取头条新闻。

天气报告: 对于天气报告,我们将使用天气报告 Web Service 在我们的 网站 上显示天气信息。

股票行情: 股票行情可以显示有关股市的最新信息。

新闻头条: 通过使用新闻头条 Web Service,我们可以在我们的网站上显示最新的新闻更新。

我们可以创建自己的 Web Service 并将其提供给他人使用。这里我们举一个例子,比如我们可以创建一个免费的 SMS 发送服务,并在页脚添加公司广告。因此,当任何人使用此服务时,他们都会间接宣传我们的公司。为了利用 Web Service,我们可以应用 N 种想法。

为了创建 Web Service,我们首先会考虑一个场景。为了创建任何 Web Service,我们首先应该了解为什么我们需要 Web Service。

Web Service 的需求

我们将考虑一个我们想在网站上展示的场景。在我们的网站上,我们想展示关于地区、国家和国际的信息。如果我们打算为所有这些功能编写代码,这将花费大量时间和精力。以上所有信息都已由一些现有网站提供,因此在这种情况下,我们想利用其他网站的当前逻辑。但问题出现了,我如何在我自己的应用程序中使用现有的逻辑呢?

这个问题的解决方案是 **Web Services**。

通过使用 Web Service,我们可以重用他人的业务逻辑,而不是复制它。要使用他人的业务逻辑,我们只需要写几行代码。这种技术类似于 API、DLL 和插件的库。

API 库和 Web Service 之间的唯一区别在于 Web Service 位于远程服务器上。

Web Services 可以被其他应用程序调用。Web Services 被称为托管在互联网上的业务逻辑片段,其他应用程序可以使用它们。

这里我们有一些关于 Web Services 的要点。

注意1:Web Services 不仅限于 .Net Framework。Web Services 的标准在 .NET 发布之前就已经定义了。Web Services 也受到微软以外的供应商的支持。

注意:2:Web Services 也可以在跨平台工作。如果服务是用一种语言编写的,那么其他应用程序就可以使用它们,尽管该应用程序使用了另一种语言。如果我们想使用 Web Services,唯一的方法就是我们需要互联网连接,然后我们将发出 HTTP 请求。

众所周知,Web Service 是跨平台的,但尽管如此,仍应有一种可理解的语言,以便我们能够请求服务并获得响应。Web Services 使用易于理解的 XML。

这正是 Web Service 构建于基于 XML 的数据交换标准之上的唯一原因。

Web Services 使用一组数据类型。XML Schema 可以轻松识别这些数据类型。

Web Services 使用简单的字符串和数字等数据类型。这些数据类型有助于与 Web Services 进行通信。而我们不能发送专有的 .NET 对象,如图像、FileStream 或 EventLogs。其他编程语言无法与这些 .NET 对象进行通信。如果我们使用某些设备将它们发送给客户端,不同的编程语言仍然无法解释。

注意:3 如果我们想使用 .NET 对象,我们可以使用 .NET Remoting。 .NET Remoting 被称为分布式技术,通过它可以我们使用 .NET 对象。但是非 .NET 客户端无法使用它。

Web Service 支持的数据类型。

  • 内置类型(基本)
    Web Services 使用的数据类型是:
    Web Services 使用内置的 C# 数据类型,如 short、int、long、short、float、char、byte、string 和 DateTime。
  • 对象: WPF 使用用户定义类的对象。尽管该类包含方法,但该类无法传输到客户端。
  • 数组: WPF 使用任何支持的数据类型(内置或自定义)的数组。我们也可以在 WPF 中使用 ArrayList。
  • 枚举: WPF 支持 enum。对于枚举值,WPF 使用字符串名称。WPF 不会使用整数。
  • XmlNode: 基于 System.Xml.XmlNode 的对象表示 XML 文档的一部分。我们可以使用 XmlNode 来发送任意 XML。

DataSet 和 DataTable: WPF 支持 dataSet 和 DataTable,但不支持 ADO.NET 数据对象,如 DataColumns 和 DataRows。

创建 Web Service

一个简单的 asmx 页面被称为 Web Service。为了创建 Web Service,我们将使用 Visual Studio 2017,它使用的是 .NET Framework 4.8。为了创建 Web Service,我们将按照以下步骤操作:

步骤 1:首先,我们将创建一个 Web 应用程序来创建 Web Service。

为此,我们将点击 File->Select Project,如下图所示:

How to create Web Service

之后,将打开一个新窗口,如下图所示:

从这里,**我们将选择 Web->Asp.Net Web Application->Web 应用程序名称->点击 OK。**

How to create Web Service

之后,会显示一个新窗口,如下图所示:

How to create Web Service

为了创建 Web Service,**我们将右键单击项目名称->点击 Add->Add New Item。如下图所示:**

How to create Web Service

之后,将出现一个新窗口。在那里,我们将点击 Web->选择 Web Service(.asmx page)->为 Web Service 命名,如下图所示:

How to create Web Service

将 Web Service 添加到应用程序后,将出现一个新窗口,如下所示:

How to create Web Service

Visual Studio 创建不可更改的 Web Service - 分析 Visual Studio 中使用的模板。

默认代码说明

[WebService(Namespace="http://tempuri.org/")]

基于 XML 的 Web Service 需要一个唯一的命名空间供客户端应用程序使用,这有助于将 Web Service 与 Web 上的其他服务区分开来。Web Service 使用默认命名空间 tempura.org。此命名空间适用于正在开发的 XML Web Services。即将发布的 XML Web Services 应使用永久命名空间。生产系统中 Web Services 实例的命名空间应替换为更具意义的 URI。

我们将通过 Web Service 中使用的命名空间来识别 Web Service;其公司将控制该命名空间。我们以公司的互联网域名为例,该域名可作为命名空间的一部分——XML Web 服务的命名空间,看起来像 URL。我们使用 URL 来指向 Web 上的实际资源。

需要注意的点

以下是在创建 Web Service 时应注意的一些要点。

  • 我们不能有多个 [WebService] 标签。
  • 命名空间的更改不会影响命名空间。

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

Web Service 不直接支持方法重载。为了允许在 Web Service 中进行方法重载,我们必须添加 MessageName 属性来区分在 Web Service 中使用的一个方法与具有相同名称和参数的方法。

[WebServiceBinding(ConformsTo= WsiProfiles.BasicProfile1_1)] 到 [WebServiceBinding (ConformsTo = WsiProfiles.None)]。

如果我们想从脚本调用 Web Service,我们将使用 ASP.NETAJAX 并取消注释以下行。

[System.Web.Script.Services.ScriptService]

[WebMethod]

此属性始终用在方法的顶部。我们将此属性写在 Web Service 中。[WebMethod] 属性用于定义使用了此属性的方法对用户/客户端是可见的。

如果移除此属性,则客户端将无法看到方法的详细信息,因此无法实现它。

代理类或 WSDL

WSDL(Web Service Development Language)文档用于生成 Web Service 的代理类。WSDL 文档定义了 Web Service。WSDL 文档包含:

  1. Web Service 公开的所有方法。
  2. WSDL 文档包含参数及其类型。
  3. WSDL 文档包含方法的返回类型。

Visual Studio 使用这些信息来创建代理类。客户端应用程序将调用代理类方法。代理类将序列化参数,准备 SOAP 请求消息并将其发送到 Web Service。Web Service 执行此方法,并将 SOAP 返回消息返回给代理。然后,代理类将反序列化 SOAP 响应消息并将其提供给客户端应用程序。无需将 .NET CLR 对象序列化/反序列化为 SOAP 格式。代理类负责所有的序列化和反序列化,这使得开发人员的生活更加轻松。

现在我们将查看 WebService1.asmx.cs 窗口

1. WebService.asmx.cs 页面包含 System.Web.Services,并且还包含 Visual Studio 在 Web 应用程序中包含的另外四个命名空间。

2. "Service1" 类继承自 "System.Web.Services.WebServices"。在从 "System.Web.Services.WebService" 继承类之后,我们可以访问内置的 ASP.Net 对象,例如(Application、Session、User、Context、Server)。如果不需要 .NET 的内置对象,那么也无需从“WebService”继承服务类。

3. "Service1" 包含 "WebService" 属性。如果我们想将任何类公开为服务,那么也需要包含 "WebService" 属性。

WebService 属性包含不同的属性,例如:

NameSpace: 使用命名空间属性可以使服务唯一可识别。NameSpace 是 XML 的属性。客户端应用程序可能包含不同的服务,因此可能会发生冲突。为了避免冲突,提供者有责任使命名空间唯一。

Name: 通过 Name 属性,我们可以为服务提供描述性名称。

Description: 此属性用于提供服务的简要描述。

4. "Service1" 还包含另一个属性,即 "WebServiceBinding"。这用于指示服务的标准。如果服务不遵循此标准,我们将收到一个异常。

5. 与服务一起添加的还有一个属性,即 "[System.Web.Script.Services.ScriptService]",为了使服务可从客户端脚本访问,服务应使用此属性进行装饰。

6. "Service1" 类包含一个名为 "Hello World" 的方法。该方法用 "[WebMethod]" 属性进行装饰。客户端应用程序访问服务方法。客户端应用程序应添加 "Service1" 方法。

服务可能使用了一些方法进行内部功能。客户端应用程序不需要使用它们。这些方法不需要用 Web Method 属性。

WebMethod 属性包含 Name 和 Description 属性,我们可以分别使用它们来提供自描述性名称或描述。

标记

现在我们将看到标记。

对于标记,我们需要右键单击 Solution Explorer 窗口中的 Service1.asmx,然后选择 view mark-up,如下图所示:

How to create Web Service

在 Service1.asmx 中,我们将看到该服务使用了带有属性的 WebService 指令。从这里可以看到,应用程序是通过 WebService 指令调用的,而不是由最终用户调用的。因此,asmx 页面没有标记。

Service1.asmx

以下是关于 Service1.asmx 的一些要点。

  • "Web Service" 指令:此指令表明 asmx 页面是一个 Web Service。
  • "Language"="C#": 这表明该服务使用了 C# 语言。
  • "CodeBehind": 此属性与 ASP.NET 或 Web Service 无关。CodeBehind 是 Visual Studio 的属性。此属性用于将 asmx 页面与后台代码页进行映射。
  • "Class" 属性包含类的限定名称。这是服务的入口点,就像 C 语言中的 main() 一样。

现在我们将按 F5 键运行此应用程序。您会发现一个指向服务描述的链接,如下图所示:

How to create Web Service

点击服务描述链接后,它将重定向到服务的 WSDL 文档,如下图所示:

How to create Web Service

还有一个指向 HelloWorld 的链接。点击此链接后,它将重定向到测试页面。

How to create Web Service

点击此链接后,它将重定向到 Service1 Web Service 页面进行测试。

How to create Web Service

Web Service 的实现

现在我们将实现服务。现在我们将把 Solution Explorer 中的 "Service1" 文件重命名为 "MyService"。我们将把类名从 Service1 改为 MyService。现在我们将打开标记(.asmx)页面。

How to create Web Service

从上面的截图可以看出,Visual Studio 无法解析类属性中的 "Service1"。这里类显示服务的完全限定名,我们已将 Service1 类重命名为 MyService,但 Visual Studio 无法解析它。

这里我们将类的属性改为 "Web application.MyService",并将 "CodeBehind" 属性从 "Service1.asmx.cs" 改为 "MyService.asmx.cs",就像我们给文件命名一样。

MyService.asmx

MyService.asmx.cs

在此之后,服务就可以使用了。现在我们将编译并运行此应用程序。

编译后,将打开一个新窗口,如下图所示:

How to create Web Service

Web Service 的测试

现在我们将通过点击 F5 按钮来运行应用程序。将打开 https://:62639/MyService.asmx 页面。该页面包含指向服务描述(WSDL 文档、Web Service 文档)的链接,以及另一个指向 SumOfNums 的链接。此页面是 SumOfNums 方法的测试页面,如下图所示:

How to create Web Service

现在我们将使用 OOP(面向对象编程概念)方法重载。现在我们在 MyService 类中添加 WebMethod。

MyService.asmx.cs

现在我们将按 F5 键运行此应用程序。将打开 https://:62639/MyService.asmx 页面,其中包含指向服务描述(WSDL 文档、Web Service 文档)的链接。这里我们还有另一个链接 SumOfNums,它是 SumOfNums 方法的测试页面,如下图所示:

How to create Web Service

在第一个文本框和第二个文本框中输入值后,它将调用该方法,如下图所示:

How to create Web Service

方法重载

现在我们将使用服务中的重载方法。Web Service 不支持方法重载。在方法重载的情况下,这将引发错误。这里我们举例说明在 Web Service 中进行方法重载并引发错误,因为它不支持重载。

MyService.asmx.cs

输出

How to create Web Service

在上面的示例中,Web Service 不支持方法重载,并显示错误消息“Service 'WebApplication7.MyService' does not conform to WS-I Basic Profile v1.1”。现在要支持重载方法,我们必须遵循以下步骤:要么删除 "[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]",要么进行一些更改 "[WebServiceBinding(ConformsTo = WsiProfiles.None)]"。

为了支持重载方法,我们需要对代码进行一些更改,如高亮显示的框所示:

经过所有这些更改后,Web Service 将如下图所示:

How to create Web Service

这里 Web Service 支持同名方法。通过添加 Message Name 属性,我们可以区分这两种方法。

通过使用上述属性,我们可以在 Web Service 中使用方法重载。

页面测试

点击 SumOfFloats 后,页面将重定向到 https://:62639/MyService.asmx?op=SumOfFloats,在这里我们将看到 "?op=SumOfNums" 已附加到 Service URL。此页面包含两个用于两个输入值的文本框(First、Second),SumOfNums 值将作为输入参数,还有一个 "invoke" 按钮。点击此 invoke 按钮后,我们将重定向到 https://:62639/MyService.asmx/SumOfFloats,它包含 SumOfNums 方法返回 XML 格式的值。

How to create Web Service

点击 invoke 按钮后,我们将重定向到 https://:62639/MyService.asmx/SumOfFloats 页面。该页面包含 XML 格式的值。

How to create Web Service

同样,在点击 "SumOfNums MessageName="SumOfFloats"" 后。我们将重定向到 "https://:62639/MyService.asmx?op=SumOfFloats"。因此,"SumOfNums MessageName="SumOfFloat"" 方法对于客户端应用程序来说称为 "SumOfFloats"。

这里有一个问题:测试页面是从哪里来的?因为我们没有添加标记,但页面仍然被渲染了。

测试页面不是 Web Service 的一部分。测试页面由 ASP.NET 使用 Web Page c:\[WinDir]\Microsoft. NET\Framework\ [Version] \Config\DefaultWsdlHelpGenerator.aspx 渲染。"Reflection"(反射)概念会渲染测试页面。

WSDL 文档

Web Services 是自描述的,这意味着 ASP.Net 本身以 WSDL 文档的形式为客户端提供了消费 Web Service 所需的所有信息。WSDL 文档告知客户端 Web Service 中存在的方法。以及方法使用的参数和返回值,以及客户端应用程序如何与它们通信。WSDL 是一个 XML 标准。

Web Service 的托管

为了托管 Web Service,我们将添加对该服务的引用并从不同的应用程序中使用它。这里我们假设端口号可能会有所不同,所以现在我们将把服务托管在 IIS(Internet Information Server)上,以获取服务器的特定地址。为此,**我们将打开 Internet Information Server->转到默认网站->右键单击应用程序->添加应用程序->浏览到我们服务的物理位置作为物理路径字段->点击 "OK"**。现在我们将使用别名 https:///WebServiceDemo/ 来浏览该应用程序进行测试,如果应用程序已正确托管。这里我们会收到一个错误 **"HTTP Error 403.14-Forbidden"**。此错误是因为没有为该应用程序设置任何默认文档。现在我们将添加一个页面作为默认文档 "MyService.asmx"。现在我们可以通过在浏览器中添加此 URL localhost/WebServiceDemo/MyService.asmx 来浏览我们的应用程序。

从客户端脚本中消费 Web Service

我们可以在任何类型的应用程序中使用 Web Service。这里我们将创建一个 .Net Web 应用程序。为此,我们将按照以下步骤操作:

步骤 1:在 Solution explorer 中右键单击->Add->New Project,如下图所示:

How to create Web Service

步骤 2: 点击 New Project 后,将打开一个新窗口,如下图所示:

How to create Web Service

步骤 3. 之后,为了与 Web Service 通信,我们必须创建一个代理类。要创建代理类,我们必须按照以下步骤操作:

代理类

为了创建代理类,我们需要在 References 上右键单击->选择 Add Service Reference,如下图所示:

How to create Web Service

点击 Add Service Reference 后,将出现一个新窗口,如下图所示:

How to create Web Service

以上窗口说明

Address: 在这里,我们将粘贴我们创建的 Web Service 的 URL,然后点击 Go。

点击 Go 按钮后,它将搜索提供的地址。

Namespace: 在命名空间中,我们将提供服务的名称,然后点击 OK 按钮。这将将 Web Service 的引用添加到项目中。

现在我们将向我们的应用程序添加 Web Form。为此,我们将按照以下步骤操作:

1. 在 solution explorer 中右键单击项目->选择 add->选择 web form,如下图所示:

How to create Web Service

点击 Web Form 后,将打开一个新窗口,我们需要在此处提供 web form 的名称,如下图所示:

How to create Web Service

在上面的截图中,我们输入了 web form 的名称,然后点击 OK。

在 Web Form 中,我们将创建一个表来使用 Web Service 提供的预定义方法。

在 WebForm1.aspx 中,我们进行了如下编码,如下图所示:

在上面的代码中,我们创建了一个表格,其中有两个文本框:textbox1 用于输入第一个数字,textbox2 用于输入第二个数字。我们创建了一个按钮,通过它可以将两个数字相加。

上述代码的设计视图如下图所示:

How to create Web Service

这里我们有两个文本框用于输入第一个数字和第二个数字。add 按钮用于将两个文本框的值相加。

双击 Add 按钮后,它将切换到编码页面。该页面是 WebForm.aspx.cs。

为了使用 Web Service 的方法,我们将对按钮点击事件执行以下代码。

WebForm.aspx.cs

现在我们将按 F5 启动 Web Service。输出将如下图所示:

输出

How to create Web Service

总结

在这里,我们在该应用程序中获得了 Web Service 的好处。我们没有为两个数字的加法编写任何逻辑。在这里,在我们的计算器 Web 应用程序中,我们只是使用了 Web Service 的方法。我们没有使用任何加法逻辑。上面的截图显示了两个数字相加的结果,即 23。


下一主题C# 中的事件