第9章 基于XML的.NET Web服务 9
内容提要 本章将介绍Web Service的原理,如何创建Web Service和使用Web Service。 如何使用ASP.NET的内部对象Session和Application。简单的介绍了SOAP协议及其应用,并介绍如何使用Web Service的数据服务。
Web服务简介 Web 服务是微软.NET策略计划的基础。一个Web Service就是一个应用Web协议的可编程的应用程序逻辑。 其中最重要的协议是简单对象访问协议SOAP(Simple Object Access Protocol)。
Web服务核心技术基础 Web 服务是一种应用程序,使用标准的互联网协议,在网上提供函数接口,用户可以从任何地方调用Web 服务。Web 服务主要使用两种技术: XML:XML可以使Web服务方便的处理数据,实现内容与表示分离。 SOAP:SOAP使用XML消息调用远程方法,SOAP是Web服务最重要的协议。
Web服务的接口描述 主要的接口方式为:WSDL(Web Service Description Language,Web服务描述语言)和UDDI(Universal Description, Discovery and Integration,统一的描述,发现和集成)。 WSDL文档用于动态发布Web服务、查找已发布的Web服务以及绑定Web服务。在WSDL中包含了使用SOAP的服务描述的绑定,也包含了使用简单HTTP GET和POST请求的服务描述的绑定。 UDDI提供了在Web上描述并发现商业服务的框架。UDDI通过服务注册,以及使用SOAP访问这些注册信息的约定。UDDI计划的核心组件是UDDI商业注册,使用一个XML文档来描述企业及其提供的Web服务。
创建并使用Web服务 案例名称:编写Web服务 程序名称:9-01.asmx <%@ WebService Language="c#" Class="Greetings"%> using System.Web.Services; public class Greetings{ [WebMethod] public string Hello(string strName) { return "hello,"+strName+",Have a great day!"; }
测试Web服务
使用Web服务 使用Web服务的过程实际上是Web服务的使用者与Web服务实现绑定,并调用其方法的过程。 绑定的方式有两种,一种是动态的,另一种是静态。动态的是UDDI实现的。静态通过WSDL文件实现。使用Web服务之前需要先生成服务代理类,然后生成服务代理程序。
生成服务代理类 命令名称:生成代理类 程序名称:9-02.bat wsdl.exe http://localhost/9-01.asmx?wsdl /l:cs /n:Ser_cs pause
生成代理程序 要让代理类被其他应用程序调用,需要利用代理类生成程序。代理程序是一个动态链接库文件(Dynamic Link Library,DLL)。 命令名称:生成代理程序 程序名称:9-03.bat csc /out:bin\Greetings.dll /t:library /r:system.data.dll /r:system.web.services.dll Greetings.cs pause
本地使用Web服务 ASP.NET程序在执行的时候,如果遇上了陌生的名称空间,就会到网站的根目录下寻找代理程序。 案例名称:ASP.NET文件使用Web服务 程序名称:9-04.aspx <%@Page language="C#" %> <%@ Import Namespace="Ser_cs" %> <script runat="server"> void Page_load(object sender,EventArgs e){ Greetings k = new Greetings(); Message.Text="Web Service返回信息为:<br>" + k.Hello("小刘"); } </script> <asp:label id="Message" runat="server" />
远程使用Web服务 Web服务主要的功能是通过HTTP被全世界的用户调用。所以通常都是被远程调用。远程调用需要利用Visual Studio.NET来建立项目。创建基于ASP.NET Web应用程序的项目,如图
在新建工程的“解决方案管理器”中,右击“引用”菜单,选择“添加Web引用”,如图
远程使用Web服务 案例名称:远程使用Web服务 程序名称:9-05.txt private void Button1_Click(object sender, System.EventArgs e){ localhost.Greetings g = new localhost.Greetings(); string strRet = g.Hello("小王"); Response.Write(strRet); }
Web 服务中的数据类型 值 说明 基本数据类型 分别是: String、Char、Byte、Boolean、Int16、Int32、Int64、UInt16、UInt32、UInt64、Single、Double、Guid、Decimal、DateTime 枚举类型 如:public enum color { red=1, blue=2 } 数组类型 如: string[] 和 int[] 类和结构 利用class定义的数据类型 数据集 ADO.NET中的DataSet对象 数据集数组 DataSet数组
创建Web服务 案例名称:使用Web Service的数据类型 程序名称:9-06.asmx <%@ WebService Language="C#" Class="DataTypes" %> using System; using System.Web.Services; public enum Mode{ On = 1, Off = 2 } public class Order{ public int OrderID; public double Price; public class DataTypes { [WebMethod] public String SayHello() { return "Hello World!"; public String SayHelloName(String name) { return "Hello" + name; public int[] GetIntArray() { int[] a = new int[5]; for (int i=0; i<5; i++) a[i] = i*10; return a; public Mode GetMode() { return Mode.Off; public Order GetOrder() { Order myOrder = new Order(); myOrder.Price=34.5; myOrder.OrderID = 323232; return myOrder; public Order[] GetOrders() { Order [] myOrder = new Order[2]; myOrder[0] = new Order(); myOrder[0].Price=34.5; myOrder[0].OrderID = 323232; myOrder[1] = new Order(); myOrder[1].Price=99.4; myOrder[1].OrderID = 645645; 创建Web服务
wsdl.exe http://localhost/9-06.asmx?wsdl /l:cs /n:DataTypes 创建代理类和代理程序 命令名称:创建代理类和代理程序 程序名称:9-07.bat wsdl.exe http://localhost/9-06.asmx?wsdl /l:cs /n:DataTypes csc /out:bin\DataTypes.dll /t:library /r:system.data.dll /r:system.web.services.dll DataTypes.cs pause
本地调用代理程序 案例名称:使用Web Service的数据类型 程序名称:9-08.aspx <%@Page language="C#" %> <%@ Import Namespace="DataTypes" %> <script runat="server"> public void Page_Load(Object sender, EventArgs E) { DataTypes d = new DataTypes (); Message1.InnerHtml = d.SayHello(); Message1.InnerHtml = Message1.InnerHtml + d.SayHelloName("Bob"); Message3.InnerHtml = Message3.InnerHtml + d.GetMode(); int[] myIntArray = d.GetIntArray(); String myString = "Contents of the Array:<BR>"; for( int i=0; i<myIntArray.Length; i++) { myString = myString + myIntArray[i] + "<BR>"; } Message2.InnerHtml = Message2.InnerHtml + myString; Order myOrder = d.GetOrder(); Message4.InnerHtml = Message4.InnerHtml + "<BR>OrderID: " + myOrder.OrderID; Message4.InnerHtml = Message4.InnerHtml + "<BR>Price: " + myOrder.Price; Order[] myOrders = d.GetOrders(); for( int i=0; i<myOrders.Length; i++) { if ( i > 0 ) { Message5.InnerHtml += "<BR>"; } Message5.InnerHtml += "<BR>Order#: " + i; Message5.InnerHtml += "<BR>OrderID: " + myOrders[i].OrderID; Message5.InnerHtml += "<BR>Price: " + myOrders[i].Price; </script> 字符串变量: <div id="Message1" runat="server"/> 使用数组变量: <div id="Message2" runat="server"/> 枚举数据类型: <div id="Message3" runat="server"/> 返回一个类或结构体: <div id="Message4" runat="server"/> 返回一个类或结构体数组: <div id="Message5" runat="server"/> 本地调用代理程序
Web服务使用ASP.NET内部对象 案例名称:使用内部对象 程序名称:9-09.asmx <%@ WebService Language="C#" Class="SessionService1" %> using System; using System.Web.Services; public class SessionService1 : WebService { [ WebMethod(EnableSession=true) ] public String UpdateHitCounter() { if (Session["HitCounter"] == null) { Session["HitCounter"] = 1; } else { Session["HitCounter"] = ((int) Session["HitCounter"]) + 1; return "访问这个Web 服务(Session) " + Session["HitCounter"].ToString() + " 次。"; [ WebMethod(EnableSession=false)] public String UpdateAppCounter() { if (Application["HitCounter"] == null) { Application["HitCounter"] = 1; Application["HitCounter"] = ((int) Application["HitCounter"]) + 1; return "访问这个Web 服务(Applicaton)" + Application["HitCounter"].ToString() + "次。";
创建代理类和代理程序 命令名称:创建代理类和代理程序 程序名称:9-10.bat wsdl.exe http://localhost/9-09.asmx?wsdl /l:cs /n:SessionService1 csc /out:bin\SessionService1.dll /t:library /r:system.data.dll /r:system.web.services.dll SessionService1.cs pause
案例名称:使用内部对象 程序名称:9-11.aspx <%@Page language="C#" %> <%@ Import Namespace="System.Net" %> <%@ Import Namespace="SessionService1" %> <script runat="server"> public void Page_Load(Object sender, EventArgs E) { SessionService1 s = new SessionService1(); s.CookieContainer = new CookieContainer(); Message1.InnerHtml = s.UpdateHitCounter() + "<BR>" + s.UpdateHitCounter() + "<BR>" + s.UpdateHitCounter(); Message2.InnerHtml = s.UpdateAppCounter() + "<BR>" + s.UpdateAppCounter() + "<BR>" + s.UpdateAppCounter(); } </script> <body style="font: 10pt verdana"> <H4>在Web服务中使用内置对象Session和Application</H4> <h5>我被访问了:</h5> <div id="Message1" runat="server"/> <div id="Message2" runat="server"/>
SOAP的结构 无论是传递数据还是执行远程方法调用,SOAP必须有一个统一的格式。SOAP首先必须具有XML格式,并且由Schema大纲定义其所包含的标记。总体上看,SOAP消息主要包括以下3个主要元素: 1、SOAP<Envelope>:它是整个SOAP消息的根元素,也是每个SOAP消息中必须有的元素。其他元素都在这个元素内部。 2、SOAP<Header>:<Header>元素是SOAP消息中的可选元素,也就是说不是每个SOAP消息中都必须有<Header>元素。但如果有,必须是<Envelope>的第一个直接子元素。<Header>元素中可以包括多个头条目子元素。 3、SOAP<Body>:这是每个SOAP消息中都必须有的元素,而且是<Envelope>元素的直接子元素。如果Envelope消息中没有<Header>元素,那这个元素必须是<Envelope>元素的第一个子元素,否则它必须紧接着<Header>元素。
SOAP的结构 案例名称:SOAP的结构 程序名称:9-12.xml <?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <MyHeader xmlns="http://www.contoso.com"> <Username>Admin</Username> <Password>MyPassword</Password> </MyHeader> </soap:Header> <soap:Body> <MyWebMethod xmlns="http://www.contoso.com" /> </soap:Body> </soap:Envelope>
定义和处理SOAP头条目 Web服务允许定义和处理SOAP头条目。定义SOAP头条目是通过继承SoapHeader类实现的。
案例名称:使用SOAP头条目实现验证 程序名称:9-13.asmx <%@ WebService Language="C#" Class="SoapHeadersCS.HeaderService" %> using System; using System.Web.Services; using System.Web.Services.Protocols; namespace SoapHeadersCS { public class AuthHeaderCS : SoapHeader { public string Username; public string Password; } public class HeaderService { public AuthHeaderCS sHeader; [WebMethod][SoapHeader("sHeader")] public string SecureMethod() { if (sHeader == null) return "错误:请提供验证信息!"; string usr = sHeader.Username; string pwd = sHeader.Password; if (AuthenticateUser(usr, pwd)) { return "验证成功: " + usr + "," + pwd; else { return "错误:不能被验证! "; private bool AuthenticateUser(string usr, string pwd) { if ((usr != null)&&(pwd != null)) { return true; return false;
编译成代理程序 命令名称:编译成代理程序 程序名称:9-14.bat wsdl.exe http://localhost/9-13.asmx?wsdl /l:cs /n:soapheaders csc /out:bin\SoapHeaders.dll /t:library /r:system.data.dll /r:system.web.services.dll HeaderService.cs pause
案例名称:使用SOAP头条目实现验证 程序名称:9-15.aspx <%@Page language="C#" %> <%@ Import Namespace="soapheaders" %> <script runat="server"> public void Page_Load(Object sender, EventArgs e) { HeaderService h = new HeaderService(); Response.Write("第一次调用:<p>"); try { Response.Write(h.SecureMethod() + "<p>"); } catch (Exception ex) { Response.Write("出现异常:<pre>" + ex.StackTrace + "</pre><p>"); AuthHeaderCS myHeader = new AuthHeaderCS(); myHeader.Username = "JohnDoe"; myHeader.Password = "password"; h.AuthHeaderCSValue = myHeader; Response.Write("第二次调用: <p><pre>" + h.SecureMethod() + "</pre>"); </script>
Web服务的数据服务 案例名称:使用Web服务建立数据服务 程序名称:9-16.asmx <%@ webservice Language="c#" Class="DBSrc" %> using System; using System.Web; using System.Web.Services; using System.Data; using System.Data.OleDb; public class DBSrc:WebService { [WebMethod()]public DataSet GetACCData(string TBName,string tiaojian1){ string x = Server.MapPath("person.mdb"); string f = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + x; OleDbConnection ACConn = new OleDbConnection(f); DataSet DS = new DataSet(); string k = "SELECT * From " + TBName+" where 姓名 like '%"+tiaojian1+"%'"; OleDbDataAdapter NComm = new OleDbDataAdapter(k, ACConn); NComm.Fill(DS, TBName); return DS; }
生成代理程序 案例名称:生成代理程序 程序名称:9-17.bat wsdl.exe http://localhost/9-16.asmx?wsdl /l:C# /n:DBService_cs csc /out:bin\DBSrc.dll /t:library /r:system.data.dll /r:system.web.services.dll DBSrc.cs Pause
案例名称:调用.NET数据服务 程序名称:9-18.aspx <%@Page language="C#" %> <%@Import Namespace="System.Data"%> <%@Import Namespace="System.Data.OleDb"%> <%@ Import Namespace="DBService_cs" %> <Script runat="server"> void submit_Click(Object sender,EventArgs e) { DBService_cs.DBSrc DBS = new DBService_cs.DBSrc(); DataSet ds = DBS.GetACCData("grade",mytext.Text); DataView s=new DataView(ds.Tables["grade"]); dg.DataSource=s; dg.DataBind(); } </script> 请输入被查询的人名<br> <form name="myform" runat="server"> <asp:TextBox id="mytext" size="50" runat="server"/><br> <asp:Button id="submit" onClick=submit_Click runat="server" Text="查询"> </asp:Button><br> <asp:label id="Message" runat="server"/><br> <ASP:DataGrid id="dg" runat="server"/> </form>
小结 本章重点介绍Web服务的创建和使用。需要掌握如何使用代理程序类和如何生成代理程序。 掌握数据服务的创建和使用方法,以及如何实现远程方法的调用。 了解如何使用SOAP头来创建Web服务。
本章习题 9-1 Web服务的核心技术基础是什么? 9-2 Web服务的接口是通过什么方式描述的? 9-5 分别在Web服务中利用Session和Application实现计数。(上机完成) 9-6 修改9-13.asmx程序,实现利用数据库的信息进行验证。(上机完成) 9-7 修改9-16.asmx程序,利用SQL Server数据库实现数据服务,并在远程调用。(上机完成)