把代码直接放到.asmx文件中或者从这些文件中引用Web服务类,都可以实现对Web服务的创建。如同ASP.NET页一样,在VS.NET中创建Web服务也使用后一种方法,目的是把问题讲述得更清楚一些。
如图26-1所示,创建Web服务项目PCSWebSrv1,此时系统会生成一系列的文件,他们与创建Web应用程序项目时所生成的一组文件相似。实际上,惟一的区别就是创建Web应用程序时生成的文件是WebForm1.aspx,而创建Web服务项目时生成的文件是Service1.asmx。
图 26-1
通过VS.NET并不能直接访问Service1.asmx中的代码,但是使用Notepad可以看到如下的代码:
<%@ WebService Language="c#" Codebehind="Service1.asmx.cs"
Class="PCSWebSrv1.Service1" %>
上面代码的作用是引用VS.NET中的代码文件Service1.asmx.cs,在Solution Explorer中右击Service1.asmx,选择View Code,就可以访问Service1.asmx.cs文件。生成的代码如下所示(为了简化起见,这里省略了注释):
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Web.Services;
namespace PCSWebSrv1
{
public class Service1 : System.Web.Services.WebService
{
public Service1()
{
InitializeComponent();
}
#region Component Designer generated code
private IContainer components = null;
private void InitializeComponent()
{
}
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
}
}
这段代码包含几个标准命名空间引用,定义了命名空间PCSWebSrv1,该命名空间包含一个Web服务类Service1的定义(它在Service1.asmx中引用),类Service1是从System.Web. Services.WebService继承而来的,它也包含与ASP.NET页面的后台编码文件(详见第25章)类似的代码。这些代码是在VS.NET中设计Web服务所需要的,其中一部分代码是一个私有成员,包含了可以添加到Web服务中的组件。为了让Web服务类正确地释放资源,还有一个Dispose()方法,它可以清理这个集合中的所有组件。现在我们应在这个Web服务类上提供其他方法。
在通过Web服务添加可以访问的方法时,需要把方法定义为public,并使方法具有WebMethod属性。这个属性可以把我们想要的方法标记为可访问的。稍后将会学习返回类型和参数所用到的类型,现在仅添加下面的方法。
[WebMethod]
public String CanWeFixIt()
{
return "Yes we can!";
}
接着编译该项目。将Web浏览器指向Service1.asmx,检查服务的工作情况(如果运行该项目,就会进入这个页面),如图26-2所示。
图 26-2
在浏览器中显示的大多数文本都说明Web服务命名空间被设置为http://tempuri.org/。这在开发过程中不是问题,但以后应修改它。为此可以使用WebService属性,但目前不修改它。
单击方法名称,可以得到SOAP请求和响应的信息,此外,还可以得到一个示例,通过该示例对如何通过HTTP GET和HTTP POST方法对请求和响应有一个感性的认识。另外,也可以单击Invoke按钮,对方法进行测试。如果方法需要简单的参数,在这个窗体中也可以输入它们。这样,就可以看到方法调用所返回的XML:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Yes we can!</string>
这说明方法运行良好。
单击图26-2的浏览器屏幕上的Service Description链接,可以查看Web服务的WSDL描述。其中最重要的部分是关于请求和响应的元素类型的描述:
<types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://tempuri.org/">
<s:element FTEL="CanWeFixIt">
<s:complexType />
</s:element>
<s:element FTEL="CanWeFixItResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" FTEL="CanWeFixItResult"
type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</types>
该描述比较长,除了包含服务的各种绑定之外,还可以包含请求和响应所需类型的描述。
1. Web服务可以使用的类型
Web服务可以用于交换表26-1中所示的类型。
表 26-1
String | Char | Byte |
Boolean | Int16 | Int32 |
Int64 | UInt16 | UInt32 |
UInt64 | Single | Double |
Guid | Decimal | DateTime |
XmlQualifiedName | Class | struct |
XmlNode | DataSet | enum |
以上所有类型的数组都是允许的。还要注意,只能编组Class和struct类型的公共属性和字段。