440 likes | 635 Views
第 7 章 Web 服务. Web 服务 (Web Service) 是一项新兴发展的技术。它以“软件就是服务”为理想目标,使得在系统架构以及软件开发等领域都发生了深刻的变化。 Web 服务是微软 .NET 策略计划的基础。一个 Web Service 就是一个应用 Web 协议的可编程的应用程序逻辑。实际上, Web 服务就是一个动态链接库 DLL ,它向外界显示出的是一个能够通过 Web 进行调用的 API 。 本章重点: ● Web 服务概要,了解 Web 服务、 SOAP 、 DDI 、 WSDL 的概念 ● 掌握创建 Web 服务
E N D
第7章 Web服务 Web服务(Web Service)是一项新兴发展的技术。它以“软件就是服务”为理想目标,使得在系统架构以及软件开发等领域都发生了深刻的变化。Web服务是微软 .NET策略计划的基础。一个Web Service就是一个应用Web协议的可编程的应用程序逻辑。实际上,Web服务就是一个动态链接库DLL,它向外界显示出的是一个能够通过Web进行调用的API。 本章重点: ●Web服务概要,了解Web服务、SOAP、DDI、 WSDL的概念 ●掌握创建Web服务 ●熟练应用Web服务的几种调用方法 ●学会使用Web服务来提供数据服务
7.1 Web服务概要 一个Web Service就是一个应用Web协议的可编程的应用程序逻辑。实际上,Web服务就是一个动态链接库DLL,它向外界显示出的是一个能够通过Web进行调用的API。用户不需要知道它的内部实现,而只需要知道他的调用函数名和参数即可。但与普通的DLL不同的是,它不存在于本地主机上,而是存在服务器端的,因此Web服务可以被任何能访问本机的网络用户调用,这就是Web服务的主要概念。
7.1.1 XML、SOAP与Web Service XML实际上是Web上表示结构化信息的一种标准文本格式,它没有复杂的语法和包罗万象的数据定义。XML提供了一种结构化的数据表示方式,使得用户界面分离于结构化数据。XML允许使用者创建和使用他们自己的标记而不是HTML的有限词汇表。这一点至关重要,企业可以用XML为电子商务和供应链集成等应用定义自己的标记语言,甚至特定行业一起来定义该领域的特殊标记语言,作为该领域信息共享与数据交换的基础。
SOAP(Simple Object Access Protocol )是一个基于XML的协议,包括四个部分:SOAP封装,封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则用于表示应用程序需要使用的数据类型的实例;SOAP RPC表示,表示远程过程调用和应答的协定; SOAP绑定,使用底层协议交换信息。
UDDI • UDDI 是一个Web Services的信息注册规范,定义了Web服务的注册发布和发现的方法。UDDI类似一个目录索引,上面列出了所有可用的企业的Web服务信息,服务服务器请求者可以在这个目录中找到自己的需要的服务。 • 企业首先向UDDI注册中心注册Web服务并提供这些 Web服务的描述。服务请求者可以使用UDDI注册中心来发现所需要使用的Web服务,然后就可以调用这些服务。
WSDL • Web service描述语言(WSDL)是这样一个基于XML的语言,用于描述Web service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应Web service的代码。
7.2 创建Web服务 在理解Web服务构架和基本访问流程后,通过VS.NET2003创建Web服务就是一件简单的事情了。在VS.NET集成开发环境(IDE)的新建项目对话框中,选择“ASP.NET Web服务”项目. 图7.2 创建Web服务对话框
代码清单7-1部分代码 …… 7:using System.Web.Services; 8:namespace chapter7 9:{ 10: public class Service1 : System.Web.Services.WebService 11: { 12: public Service1() 13: { 14: //CODEGEN: 该调用是 ASP.NET Web 服务设计器所必需的 15: InitializeComponent(); 16: } 17: #region 组件设计器生成的代码 18: //Web 服务设计器所必需的 19: private IContainer components = null; 20: /// <summary> 21: /// 设计器支持所需的方法 - 不要使用代码编辑器修改 22: /// 此方法的内容。 23: /// </summary> 24: private void InitializeComponent() 25: { 26:}
27: /// <summary> 28: /// 清理所有正在使用的资源。 29: /// </summary> 30: protected override void Dispose( bool disposing ) 31: { 32: if(disposing && components != null) 33: { 34: components.Dispose(); 35: } 36: base.Dispose(disposing); 37: } 38: #endregion 39: // WEB 服务示例 40: // HelloWorld() 示例服务返回字符串 Hello World 41: // 若要生成,请取消注释下列行,然后保存并生成项目 42: // 若要测试此 Web 服务,请按 F5 键 43: //[WebMethod] 44: //public string HelloWorld() 45: //{ 46: // return "Hello World"; 47://} 48: } 49:}
去掉红色注释部分,使服务有效,运行该Web服务页面去掉红色注释部分,使服务有效,运行该Web服务页面 图7.4 Web服务运行界面
图7.5 测试HelloWorld方法 图7.6 运行服务的结果
在VS.NET开发项目中,应用最多的可能莫过于访问数据库,开发企业级应用软件时需要大量与数据库进行交互。特别是在集团化的分布式管理应用中,采用先进的Web Services(Web服务)分布式技术,构建覆盖集团所属企业单位的信息体系,实现集团总部、直属企事业单位、下属全资、控股子公司之间的信息的实时传输和集中管理。程序清单7-2是利用Web服务访问数据库,检索所有学生的成绩,返回数据集。
程序清单7-2 1:[WebMethod] 2:public DataSet get_grade() 3:{ 4: string connstr="provider=microsoft.jet.oledb.4.0;data source="+ 5: Server.MapPath("student.mdb"); 6: OleDbConnection conn=new OleDbConnection(connstr); 7: OleDbDataAdapter da=new OleDbDataAdapter ("select * from grade",conn); 8: DataSet ds=new DataSet(); 9: try 10: { 11: da.Fill(ds); 12: } 13: finally 14: { 15: da.Dispose(); 16: } 17: return ds; 18:}
7.3 使用Web服务 • Web服务的主要作用就是为了供客户端程序调用,由于Web服务是在遵循SOAP协议的基础上采用WSDL(Web服务描述语言)语言描述的,因此可以采用以下方式来使用Web服务。 • 通过Web引用方式使用Web服务 • 通过代理类来使用Web服务 • 使用Microsoft SOAP工具包使用Web服务
7.3.1 通过Web引用方式使用Web服务 1.添加Web引用
选择本地的Web服务 图7.9 添加Web服务的对话框
2.通过服务类的实例调用方法 1:private void Page_Load(object sender, System.EventArgs e) 2:{ 3: get_stud_grade gsg=new get_stud_grade(); 4: this.DataGrid1.DataSource=gsg.get_grade() . Tables[0].DefaultView; 5: this.DataGrid1.DataBind(); 6:} • 在test.aspx页面的Page_Load事件中,编写如下代码,调用该Web服务的get_grade()方法,获取成绩表中的成绩信息,并把它放到DataGrid1中显示出来。
7.3.2通过代理类使用Web服务 创建Web服务代理类可以使用.NET命令行工具wsdl.exe来完成。该工具的使用格式如下:wsdl [options] {URL | path},其中URL是指向WSDL 协定文件(.wsdl)、XSD架构文件 (.xsd)或发现文档 (.disco) 的URL。Path是本地WSDL协定文件(.wsdl)、XSD架构文件 (.xsd) 或发现文档(.disco或.discomap)的路径。
步骤1 生成代理类 要针对前面编写的7-2服务生成代理类,首先通过“Visual Studio .NET 2003 命令提示”进入DOS提示符操作界面,在提示符下键入以下命令:wsdl /n:Get_GradeNS /out:get_grade.cs http://localhost/ chapter7/7-2.asm
生成的代理类get_grade.cs清单 1:namespace Get_GradeNS { 2: using System.Diagnostics; 3: using System.Xml.Serialization; 4: using System; 5: using System.Web.Services.Protocols; 6: using System.ComponentModel; 7: using System.Web.Services; 8: 9: /// <remarks/> 10: [System.Diagnostics.DebuggerStepThroughAttribute()] 11: [System.ComponentModel.DesignerCategoryAttribute("code")] 12: [System.Web.Services.WebServiceBindingAttribute(Name="get_stud_gradeSoap", Namespace="http://tempuri.org/")] 13: public class get_stud_grade : System.Web.Services.Protocols .SoapHttpClientProtocol { 14: 15: /// <remarks/> 16: public get_stud_grade() { 17:this.Url = "http://localhost/chapter7/7-2.asmx";
18: } 19: 20: /// <remarks/> 21: 22:[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/get_grade", RequestNamespace="http://tempuri.org/", ResponseNamespace="http://tempuri.org/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)] 23: public System.Data.DataSet get_grade() { 24: object[] results = this.Invoke("get_grade", new object[0]); 25: return ((System.Data.DataSet)(results[0])); 26: } 27: 28: /// <remarks/> 29: public System.IAsyncResult Beginget_grade(System.AsyncCallback callback, object asyncState) {return this.BeginInvoke("get_grade", new object[0], callback, asyncState); 30:} 31:
32: /// <remarks/> 33: public System.Data.DataSet Endget_grade(System.IAsyncResult asyncResult) { 34: object[] results = this.EndInvoke(asyncResult); 35: return ((System.Data.DataSet)(results[0])); 36: } 37: } 38:}
步骤2 编译代理类生成程序集 图7.13 编译代理文件为DLL组件
步骤3 在项目中引用程序集 图7.14 通过本地代理访问远程Web服务
7.4 使用Web服务的数据服务 作为一个Web服务,它是可能被任意类型的客户端程序访问的。因此有必要为Web服务提供一套统一的具有广泛意义的数据类型。为了做到这一点,.NET框架中的Web服务使用了XML Schema Definition语言中定义的数据类型,因为这些数据类型可以被XML编码和序列化。 表7-2 可在Web服务中传递的数据类型
7.4.1 使用Web Service完成数据查询 在.NET应用中,经常需要查询数据库中数据,由于DataTable、DataView、DataRow等类型的对象都不能被序列化,把DataTable的值存放在数据集中,利用Web服务返回,供用户调用。
1.创建服务 程序清单7-5 1:[WebMethod] 2:public DataSet index_grade(string stud_id) 3:{ 4: string connstr="provider=microsoft.jet.oledb.4.0; data source="+ 5: Server.MapPath("student.mdb"); 6: OleDbConnection conn=new OleDbConnection(connstr); 7: string sql="select * from grade where stud_id='"+stud_id+"'"; 8: OleDbDataAdapter da=new OleDbDataAdapter(sql,conn); 9: DataSet ds=new DataSet(); 10: da.Fill(ds); 11: da.Dispose(); 12: return ds; 13:}
2.引用服务 1:private void Button1_Click(object sender, System.EventArgs e) 2:{ 3: string stud_id=this.stud_id.Text.Trim(); 4: Service2 s2=new Service2(); 5: this.DataGrid1.DataSource= s2.index_grade(stud_id); 6: this.DataGrid1.DataBind(); 7:} 运行界面
7.4.2 使用Web Service向数据库添加数据 在很多情况下,不同的应用程序需要共享一个数据库,而这个数据库出于安全的考虑,并不想向其它应用程序或用户提供用户名和密码,此时Web服务不失为一种好的方法。通过它开通数据库的查询或更新操作,完成特定的任务,然后返回结果。
1.创建服务 1:[WebMethod] 2:public bool add_grade(string stud_id,string course_id,int grade) 3:{ 4: string connstr="provider=microsoft.jet.oledb.4.0; data source="+ 5: Server.MapPath("student.mdb"); 6: OleDbConnection conn= new OleDbConnection(connstr); 7: string sql="insert into grade values('"+stud_id+"','"+ course_id+"',"+grade.ToString()+")"; 8: OleDbCommand comm= new OleDbCommand(sql,conn);
9: try 10: { 11: conn.Open(); 12: comm.ExecuteNonQuery(); 13: return true; 14: } 15: catch 16: { 17: return false; 18: } 19 finally 20: { 21: conn.Close(); 22 } 23:}
2.引用服务 1:private void Button1_Click(object sender, System.EventArgs e) 2:{ 3: string stud_id=this.stud_id.Text.Trim(); 4: string course_id=this.course_id.Text.Trim(); 5: int grade=Int16.Parse(this.grade.Text.Trim()); 6: Service3 s3=new Service3(); 7: if(s3.add_grade(stud_id,course_id,grade)) 8: { 9: RegisterStartupScript("message","<script> alert('添加成功!');</script>"); 10: } 11: else 12: { 13: RegisterStartupScript("message","<script> alert('添加失败!');</script>"); 14: } 15:}
7.4.3 使用Web Service传送二进制文件 Web服务也可以用来传送一个二进制文件,比如一个程序或一张图片。这种实现是通过读取二进制文件,并转化成byte数组,然后作为Web服务的返回值进行传送。在Web窗体中,调用该Web方法,利用byte数组生成一个图片文件,就可以达到接收二进制文件的目的。
1.创建Web服务 1:[WebMethod] 2:public byte[] get_image(string image_path) 3:{ 4: if(File.Exists(image_path)) 5: { 6: try 7: { 8: FileStream fs= new FileStream( image_path,FileMode.Open,FileAccess.Read); 9: int bytes; 10: byte[] image_byte; 11: MemoryStream ms=new MemoryStream(); 12: while((bytes=fs.ReadByte())!=-1) 13: { 14: ms.WriteByte((byte)bytes); 15: }
16: fs.Close(); 17: image_byte=ms.ToArray(); 18: ms.Close(); 19: return image_byte; 20 } 21: catch 22: { 23: return null; 24: } 25: } 26: else 27: { 28: return null; 29: } 30:}
2.引用服务 private void Page_Load(object sender, System.EventArgs e) { Service4 s4=new Service4(); byte[] image_byte=s4.get_image(Server.MapPath("winnt.jpg")); if(image_byte!=null) { MemoryStream ms= new MemoryStream(image_byte,0,image_byte.Length); Bitmap bitm=new Bitmap(ms); bitm.Save(Response.OutputStream,ImageFormat.Jpeg); } } 图7.17 接收Web服务传送的图片
本章小结 本章重点介绍了Web服务的创建、使用,以及几种常用的调用Web服务方法。需要熟练掌握如何使用Web服务,包括如何通过引用Web服务和生成代理类来使用Web服务。需要注意的是Web服务需要发布和部署在Web服务器上才好访问和调用。
思考练习 1.Web服务方法与普通类的方法有何区别; 2.WSDL的作用是什么? 3.创建一个Web服务,用于计算两个整数的乘积。如果用户输入的数据类型错误,返回错误消息。 4.基于student.mdb学生数据库创建一个Web服务,检索某班学生的所有成绩。