圣弗兰西斯卡
Anders Hejlsberg
2002年2月13日,星期二
主持: 女士们,先生们,请欢迎最卓越的工程师:Anders Hejlsberg
(掌声)
Anders Hejlsberg: 谢谢。在开始今天的题目之前,我想先带大家回顾一下历史,从早期的计算到现在我们到了何种状态。我相信如果我们回头看一下计算机与分布式应用,你将看到每十年左右都会有变化。回到70年代,你知道,几乎所有的计算都运行在一台服务器上,她被放在后面的房间里,然后前台有傻瓜中断以合适的协议与它相连。
到了80年代,你会发现,应用的重心开始转移到客户端,文件服务器只是提供文件的分类存储。很多计算不是在服务器上实现的,而是在客户端实现的。
现在到了90年代,互联网的时代,应用的重心由转到了服务器端。互联网就好像是一个旧的IBM的3270终端,只是你会联结多个网站而不是一个放在房间后面的服务器。当然,HTML是一个更丰富的协议。
现在,人们开始谈论也许现在该转向另一个时代,趋向于客户端,在这一个点到点的计算时代。但事实上,我们相信现在是一个最终走向平衡的时代。我们将同时计算放在服务器端,也会放在客户端。我们将依然会做很多是在服务器端,先我们现在一样,同时我们也会利用技术的革命,比如手写体识别技术与语音识别技术,将应用放在客户端。
换句话讲,我们将拥有两种最佳的计算世界。这也是一个理由,我们相信会有一种更丰富的协议,一个构架,允许我们拥有两端智能的应用,那就是XML与 Web 服务。
关于XML Web服务的一件事,当然,是一个自然的转移,让我们来看.NET:是一个在何时何地都可以访问的信息。但不管你问谁,它都是一组分布式的计算,一个分布式的应用,一组连接的应用。并且我们相信,XML与web服务将成为这些分布式应用的连接架构。当然,随着这自然变化,将带来一组工具的变化。
让我们来看,我们现在在哪里。是一些有历史意义的一些工具,从几十年前的文本模式的应用,到图形界面的应用,到现在领导互联网的一些工具。还有今天我们要谈到的有创新意义的一组工具.NET 框架与Visual studio.NET.
当我们发布Visual studio 6.0,那已经是三年半,四年以前,我们知道我们创建了一组极好的工具,可以使客户创建很好的应用,但我们知道我们可以在开发工具方面可以做得更好。
例如,我们意识到创建分布式的应用于连接这是应用非常复杂。如果让我们来看那些创建分布式应用与连接分布式应用的技术,而且我们至今还再用者的技术:DCOM, Corba, IIOP, RMI. 我们知道那是一组字符串,但非常难开发与维护。我们知道我们可以做得更好。
我们也知道我们有很多很难的编程模型,与很多很难的编程语言难以集成。你知道,我们有Visual Basic与C++,ASP等等。我们知道我们的面向对象系统,COM, 在许多方面不够丰富来创建今天人们想创建的应用。COM不能够支持一些关键的面向对象的的概念,例如继承与多态,同时我们知道,COM太复杂了。COM是一个非常低层的二进制标准。你不得不自己做很多整理工作,例如担心结果,与增加refs, release, GUIDs等等。
同时,我们与W3C联盟一起在XML的标准之上的工作中,看到一些互联网上跳跃式的发展,并知道将有一组新的应用将在此基础上建立。
但看看所有眼前的事实,我们不可能只是通过修改一下COM,DNA就能有革命性的创新。我们知道,我们需要创建一个新的平台。
这个平台就是.NET 框架。她是一个内置支持XML web服务,统一我们所有编程模型,并能大大简化开发,提供了一个强大的,持久的,安全的执行环境,支持多种编程语言,并最终允许我们将原有投入精力写的代码得以集成。
现在,在我结识如何构建这一框架,以及详细介绍之前,来让我给你们看一下这个框架的示意图。
她开始于底层的操作系统,在操作系统之上,我们叫他“通用运行时”(common language runtime) .这是一组组件,在平常的工作中看不到。她提供了所有核心的服务比如类库加载,编辑,意外处理,垃圾收集,安全性,等等,等等。所以它是一个黑盒子,让你可以在.NET世界里执行代码。
在通用运行时上面是一组类库,开始于基类库,它提供一组最通用的功能比如:文件输入输出,串处理,例如访问TCPIP等等。
在这之上,我们有ADO.NET,这是下一代的支持XML web 服务的ADO版本,我们的XML堆(stack)开始于一个低端的XML parser, 通过一个与W3C DOM兼容的XML 文件模型工作,并且也支持X-PATH于一组其它的XML标准。
在类库上面有两个框架。我们有服务器端的框架和客户端的框架。在服务器端,我们有ASP.NET, 我们的应用服务器,Web forms, 那是一个在ASP.NET里写表单的编程模型。她支持Web服务与移动互联网工具集,并且允许你为移动设备创建UI.
在客户端,我们有Windows Forms, 你可以把它当作把Visual Basic 表单与MFC放在一起的一种革新。你可以在Windows表单世界里,将最优化的两种特征兼顾。
再往上,我们可以看到叫做通用语言规范,它是一个标准,是所有的语言必须支持一个最小的功能集合,以便于所有语言可以运行在.NET通用运行时上。
并且我们提供了支持这种通用语言规范的四种语言:Visual Basic, C++, C# 与 J#. 但实业界的合作伙伴正在创建,你知道,到目前,我们已经有超过20种的语言支持通用运行时。
最终,当然,支持所有功能特性的是Visual studio.NET.
那么现在来看一下我们如何创建这一开发工具以及何种动力产生了这一框架。
谈到这里,让我们看一下我们为什么会有这么多的复杂的编程模型,纠其原因,其实都是一个历史过程,让我们来看我们如何编写Windows应用的。让我们回溯到10或甚至15年,写一个Windows应用,实际上只有一种方式来做。你会启动你的C便一起。你可能会:include Windows. H. 你会翻开书,你会写Win cross与Windows 消息处理器。那些都非常复杂,并且没有工作效率。
然后,随着时间的推移,我们看到一些不同的编程模型。例如,Visual Basic 开创了一种快速开发方式,利用表单来设计程序,用这种方式,你知道,可以从一个工具面版上拖放“控制”放到一个表单中。然后你可以写一些时间处理器,使得代码都放在后台。
但C++就走了另外一条道路,利用MSC与ATL. 这里我们用一些不同的范例,如Sub classing. 当然,这样使你更轻大,并可以更好的表示,但他当然没有Visual Basic使用起来容易。
最近,随着互联网的发展,我们看到一整套新的编程模式的崛起,围绕在服务器端执行的HTML页面,与ASP编程模型。
然后你一定会想象,我们会继续下去,并且将有一种新的编程模型来写Web服务,与一种新的编程模型来写移动UI, 但是有一个不幸的事实。一个是你不经意间选择的编程模型会决定你选择编程语言。
例如,如果你想到MSC, 如果你是一个VB的编程人员,并且有一些MSC或ATL你想使用。她不只是一种简单的可能。反之,VB表单只能从Visual Basic中得到。如果你想写一些HTML 页后面的代码,你只能用描述语言。
另外一个问题时,每种不同的编程模型,都对通用的问题有着不一样的解决方案。例如,
在不同的编程模型中,对于文件的输入输出,就有不同的处理方式。
现在,.NET 框架所作的事情,就是统一这些编程模型,提供一种一致API,不管你所用的语言,也不管你用了何种编程模型。
现在,我来讲以下.NET框架的另外一个目标是大大简化编程。在这里,.NET框架提供了很多方式,我不能够例数所有的方式,但我放了一些重要的在这张幻灯片中。
首先,我认为.NET框架所作的是提高了抽象层。如果你今天来看COM, 他是一个非常低级的二进制标准。我不知道你们是否作过C++与COM的编程,它是可怕的。你知道,你不得不处理H结果与GUIDs与增加refs与release, 直是到处都有丰富的机会来藏有bugs. 正向我所说的,COM在今天来看,并不足够丰富。她不支持核心的面向对象的概念。
.NET框架是你远离这些麻烦,它只是完全自动的去处理这些事情,让你可以从杂物中解脱出来,并集中思想到运算规则上。
另外一个问题是,.NET框架是如何统一编程系统的。在.NET框架中,每件事都可以看作是一个对象。甚至一个INT也可以看作是一个对象,或一个float. 没有变量;所有都是对象。所以就没有在Visual basic中在变量与对象中的二分法。将会有一个字符串绑定在整个平台,并且所有字符数据都是Uni-Code.
最后,这一平台提供了面向对象的编程或软件组件的编程方式。例如属性,方法,事件都是.NET框架中的第一级的结构。所以他不象如果你用C++来写一个Active X 控件,你不得不用一些宏来定义属性,以及事件等等,这些所有的支持都内置在.NET框架的开发语言中。
另外一点是:组织这些API的方式。过去人们用Win32API, 实际上是一个巨大的扁平的API. 那里根本没有任何组织。我们对这些30000个入口最好的办法就是按照字母排序,但请看在.NET框架中,所有一切都被逻辑化的组织明且命名。所以如果你看到一些关于输入输出的东西,就可以去看System IO,然后你会找到叫”文件“的类库,所以它可以很容易的带你到你想要的地方。
另外一种方法来看是否我们简化了编程,就看一下我们以前如何写代码,现在又是如何写代码。这里是一些我喜欢的,一些例子,调用Windows API来生成Windows. 你首先调用Creat.windows.ex然后把它送给至少12个参数。然后你需要更新一下窗口,来显示一下屏幕上的状态。
对比一下你所做的,把它放在.NET框架中。你生成一个表单。你用了Caption,然后你显示出来。
现在,你所做的许多都是一个VB程序员会做的事。“我们已经这样做了好几年. 到底有什么新鲜花样?“ 我认为有几个新的地方,对比今天的VB编程方式。首先,今天的VB,为了让你容易得拿到APIs. 一些人不得不事先打包API把它变成COM APIs. 这也是为什么VB有些滞后。通常,当新的API出来,他们首先是由C的编程方式生成,然后VB 工作人员再把它打包成容易使用的API.
第二个问题,当然,一旦这些APIs被打包,你就不能真的与其他人说相同的语言,因为别人在一个低级别的API上并且一些文档不能用,一些东西不能够打包,因此你不得不丢到这些,或者那些,你喜欢的功能。
但我认为也许最重要的事我们-微软将如何编辑这些API. 他不会是一些低级别的官样文章。我们将把抽象层向上移,使新的API容易使用,程序员只需要关注于所要做的事情,也就是说不需要完全懂得所有的API才能够写最简单的应用程序。
我认为另外一个重要的事情就是.NET框架提供了一个功能强大的持久地执行环境。在.NET框架中,所有对象都是自动地执行垃圾收集与内存管理。
现在,事实上,在COM与.NET框架中,内存管理是完全不同的。在COM中也有自动的内存管理。但它是用一个叫做reference counting的方法来处理,用这种方法来计数代表每个对象的reference的数量。如果没有遇到一个难题,到目前为止他工作的非常好。这是一个循环reference的问题。如果你有两个对象,每个都有一个reference指向对方, 而对于内存管理来讲,这些对象就始终是活的,然而没有其他reference他们并且你生成了一些内存岛,永远不会被收集。
.NET框架使用不同的技术来实现内存管理,叫标记(mark)与清扫(Sweep), 我不打算将太多细节他是如何工作,但最根本的他完全解决了reference counting的问题。
另外一个提供强大执行环境的关键是意外处理。你已经熟悉了在VB中的“on error go to”,它确实是提供了一些少量的结构化的错误处理。但仍然有些错误处理会更复杂,当一个错误出现在.NET 框架中,每个意外处理都会带有一个错误描述信息。你可以获得一个错误信息堆栈,并能精确知道什么出了错,并错在哪里。
在.NET框架中也许最重要的错误处理就是强制性的处理。 如果你们看一下,传统的Windows API是如何工作的,所有语言是如何工作的,比如C, C++等等,错误处理总是一个随意的事情。一个API也许可以返回一个错误代码或一个结果代码来说明这个API是工作还是不工作,但除非你会写一些代码来检测这些错的结果,你知道,否则任何事都不会发生。事实上,你的应用将会处于混沌状态,然后三个或四个API调用会启动,因为一个空指针或者你没有任何想法如何结束。
不只是意外处理。如果一个意外处理发生了,如果你的应用没有处理这个意外,然后你的应用就会关掉。他们会有序的关掉,并提醒你,你有丰富的时间去解开现有的状况等等,但我们最终不会陷入混沌,这样就会减少很多bugs.
类型安全是另外一个带来强大的原因。在.NET框架中不会有不安全的类型表。你不会产生某一个类型的指针指向另外一个类型,执行引擎会简单的拒绝她。不可能有位初始化的变量。你不可能索引,超出他的边界的数列等等。
一个关键的功能就是我们的零冲击安装功能。这时,事实上是我喜欢的功能之一。在.NET框架中,绝对不需要为了运行而注册的说法。你可以生成一个子目录,把应用拖到哪里,运行他,当运行结束,你就可以删除目录,不管你在什么机器上运行,都不会留下痕迹。
(欢呼,鼓掌)
这不是说你的应用不能共享信息。我们也支持另外一个模式,当我们安装进一个global assembly cache, 正如我们所说的,然后应用可以共享类库。
另外一个关键,我认为,在.NET框架中的革新是Side-by side执行,这允许你可以在相同应用利在你的机器上运行与安装不同的版本代码。你可以有应用版本1.0,应用版本2.0
并且你可以并行运行他们。你甚至可以在相同的进程中运行从这些应用中出来的对象。
这也就意味着,你不再有哪些DLL hell问题,当你安装一个新版本的DLL, 你的应用在从前的时候会因为它而终止。
而代替它的是,在.NET框架中,你的应用将继续会根据版本而运行。所以,正像我所说的,你可以有一些数据库支持的库版本1.0,1.1 与2.0, 各种不同的应用可以继续使用不同的版本,因此默认情况下当你在机器中安装了新的的应用,你的应用也不会中断。
所以.NET框架是一个多语言的平台。从最初我们设计这一平台,我们就知道我们想要在这一平台上支持多种语言。对我们最重要的不是让人们只学一种语言,而是让他们可以利用以前他们已经知道的编程语言经验,并且已经编写的代码。
另外一个关键,.NET框架中所支持的语言都是一流的。我提到过一些早期的事实,API不能用于今天的VB如果他没有第一时间打包成一个COM对象。这在.NET框架张绝对不成问题。任何API发布到.NET框架中,都可以立即被VB或任何在这一平台上实现的编程语言来使用。
事实上,我们的集成能力已经远超过我们现在所看到的。例如,你可以用一种语言写一个类, 从另外一个语言中继承,并且从第三种语言例示。这种集成能力可以如此之深。
当然,它也意味着你可以高度整合这些开发工具。你实际上只需要一个集成的开发环境,一个Debugger来使用这些多语言。
现在我们提供了5种语言:VB, C++, C#, J# 与Java Script 或者J script. 但是在业界,学术界,有很多其他语言被开发,以及正在开发,包括一些语言如:Cobo, Fortran 与APL.
现在,我曾经提到.NET框架允许你高度的集成存在的代码。因为你的所有语言都创建在这一公共的基础之上,叫做.NET框架的公共基础之上。你可以看到.NET框架在语言之间的集成能力是比我们以往所见的任何架构都强。
其实在性能上,能力上,在这一平台上写一个Visual Basic或C#或J script 或任何其他这一平台支持的语言都没有太多差别。
但是在现实世界里,只是语言的互操作是不够的。当然,有很多代码不是为.NET框架写的,我们也希望能够完全的利用上,所以.NET框架提供了在DLL之间的互操作性,在DLL中的代码,通过一个叫做 P 调用, 来实现DLL与COM或OLE自动对象的互操作。事实上,任何你在.NET框架中写的代码都可以在框架之外看作是一个COM对象,反之亦然,任何COM对象,可以自动输入到.NET 框架中,被看作是一个类放在哪里。
然后最终,我们通过XML和SOAP,我们提供了可能是最好的,最灵活的方式来在异类的系统中集成。
所以有很多互操作简单的内置在里面,因为我们相信摩尔定律――至少在我的思想中,摩尔定律已经离我们很远。我们会如何以用Gigaherz的CPU与512 megabytes的内存?回溯以前64K或640k的内存,你也许每次都会感到困难,也许要花六个月来写一个程序来利用所有的机器容量。你已经远离那个时代。但今天,你不会与要这样的问题,我的意思是,客户期望越来越多的容量,好像用不完的容量,我们不得不找到方法来利用以前已经写过的代码。
所以,我转移一下话题,来谈一些web service. 关于web service的革命,我认为我们正在当中,Visual studio.NET与.NET框架,会将起重要作用。
在我们做演示之前,我想讲几张幻灯片来解释一下我所认为的web service. 实际上简单得像可以认为它是一个花生壳,如果HTML是使人与机器可以交互沟通的话,XML与SOAP就是关于机器与机器的沟通机制。更精确些,它是一个相同的结构。
现在我来讲一下,传统的分布式计算,是如何利用DCOM, Corba, RMI等等来连接应用。 那什么是web service来提供的更好的技术来写这些分布式的应用。
我认为有三个关键的因素。首先,XML web service充分利用了Web. 他们有着与创建HTML应用相同的架构。所有在网络上传递的一切都是通过HTTP协议。所有都一样。唯一改变的就是web service 代替了传递HTML, 你在HTTP基础上传递XML.
当然,这样就给我们很好的机会可以利用以前的web 应用,使原来的web 应用变成web service 也许只需要简单的增加几行代码,或一页代码在网站上。
第二件事情是,web service可以使你真的可以在异构系统集成。任何种类的应用结构都必须支持的异构系统环境的集成。你不需要要求应用的两端都运行在相同的OS上。你甚至于不需要应用的两端都用相同的中间件。有了web service, 你的应用的一端可能是在.NET框架上,应用的另一端可能是运行在Apache server上,运行着perl script,但输出XML的数据格式。
最后一件事,我认为web service允许你创建真正的可扩展的应用。再次,让我们看一下传统的分布式应用技术。他们都用了所谓远程调用的技术如:DCOM, Corba等等,他们真的使得这个世界看起来像是面向对象。她正好是一些对象运行在这台机器上,一些对象运行在另外一台机器上。但是这个架构只有在内部处理通讯,在一台机器上,或在一个本地的内部网络中,它可以执行得很好。但当你开始扩展你的应用时,比如你的客户端在旧金山,而你的服务器在纽约,你就会出问题。因为在这种旧的技术中,它基本上是,试图隐藏一个事实,你的应用不能够足够分布,当分布的距离分布到无限的网络上时,就会出问题。当你提出一个调用,但需要等很久,你不得不持续保持呼叫状态,但这真者的会伤害到可靠性,因为你不可能fail over. 而且你也不能做一些饶舌的沟通当你在调用一个对象时,对方回话后然后离开。“噢,谢谢”“噢,别客气”等等。当你在一台机器上这所有一切都会很好,,但是当你要对东海岸对话时,你真的需要了解对方的状况时,光速就会出现问题,。
现在,对比XML web service, 有很好的证据存在着,它可以扩展到任何你以前达不到的地方。因为我们已经今天在HTML上看到了很好的扩展。正如我所说的,我们改变的只是传递的东西,从前是HTML, 现在是XML. 但所有的架构都一样。我们知道如何扩展,我们知道它可以扩展。
所以什么是web service的基础?当然,它起源于唯一的有互联网提供的通讯,在这一通讯机制上,我们存储通用的由XML提供的数据结构,XML可用来传递任何数据。
现在,在XML之上我们有很多变化了的协议,我们有XSD来描述类型。我们有SOPA来描述交互或web service的调用。我们有WSDL, web service 描述语言来描述web service. 我们有发现协议。
在这之上,我们有web service的黄页,注册的服务叫做UDDI.
现在,最关键的就是我们有简单的开放的标准,并且有广泛的业界支持。这些都不是微软制定的标准,这些标准是我们与业界合作伙伴以及与标准组织如W3C合作创建的
所以一个web service 是如何工作的?让我来举例,假设我是一个web service的消费者,我想使用web service. 首先,我会找到我想要得web service. 我不得不在web service 世界里去寻找。我可以有几种方法。我或者到UDDI去找,或者到特定的业务区域里去寻找。这些特定的区域支持特定的schema,数据按各种方法排序。但通常,我会的得到一个连接,一个web service描述语言文件,告诉我关于我所找到的web service.
或者我也可以直接找到我要找的web service的组织,说我已经知道他们的网址,并且获得了disco文档或一个发现文档,它基本上是一个目录,所有的web service都在这一地址上。
另外一个状况是,我最终找到一个WSDL文件或者一个Web service描述语言,或者我找到了一个连接,这个连接可以让我找到WSDL文件。通过这个文件,我可以知道如何与Web service通讯,最后一步就是利用基于XML的SOAP协议来与这个服务对话。
现在,在幻灯片最上面的三个步骤是设计时步骤,如果你愿意,没有任何步骤在运行时发生。只有最后一步是在运行发生。但所有以上三步都完全支持Visual studio. 我可以从Visual studio中找到UDDI的注册处。我可以获得Discovery(发现)文件或者一个WSDL文件,并且Visual studio自动为我生成web service的代理服务。以便于我只需要简单的调用一个方法,带来一些参数,然后所有的基础结构的事情被自动处理了。
这也就是什么是web service. 现在,我们来看一下,.NET带来了什么?如果来看一下你是如何开发应用的,有一些概念在你的开发过程中一直是通用的。你的应用趋向于处理数据。并且趋向于结构化这些数据。你的应用完成一些服务,例如,应用的功能,有一个政策是关于应用是如何调用的。
现在,让我们来看一下web 上已存在的标准,或者存在的,或者即将出现的。数据可以描述成XML. Schemas可以描述成XSD. 服务可以描述成WSD,调用可以使用SOAP协议来实现。
但当你写代码时,你真的不知道XML与XSD等等。你知道更多的是关于的数据,与你的对象。对于你的Schema你可以把它看成是这些对象的类。对于你的服务,也就是你的应用的方法,或者是你的应用的功能,也就是说,调用就好像是调用这些方法。
然而,.NET框架的价值就是给你提供这些概念的双向映射,这些概念就是你作为一个程序员已经知道的概念,与今天现在在互联网上已经存在的概念。
所以.NET框架可以把,例如,任何对象,自动转换成XML,反之亦然,它可以把XML再转回成对象。另外,它可以把一个类,生成一个XSD结构的Schema,相反它也可以把一个XSD的Schema转换成类。
所以基本是,.NET框架可以让你是用你已经适应的编程术语,框架自己回去处理与互联网结构的映射。
为了说得更清楚些,这了让我给大家演示一下,web service是什么样的。比如说,我写一个订单处理的类,它有一个提交订单的方法。并且提交订单会带来一个购买订单的对象。为了把这个转成一个web service, 我实际上不需要修改代码的任何部分,我只需要给这个代码家一个属性,一个 Web method 的属性,它告诉系统,请把这个方法发布到互联网上。
现在,我也许实际上想再多加些代码,比如控制这个XML 可以跨越有线网络,所以我可以给我的购买订单加一些属性,来指定当这个对象转换成XML时,请把它放到XML的命名空间。对我的对象的每一个域,我可以指定我是否让他映射到XML属性或到XML元素。
但是这里关键的是,我可以写一些代码像现在这样,我也可以用另一种语言来写他,例如,这里我是用C#来写Web service的,我可以在客户端用VB的代码来调用他。当我做了一个新的购买订单后, 我可以让他把东西寄给我,然后把帐单寄给Bill,并且要今天做,然后提交订单。
来看看,当我做这些时,.NET框架中会发生什么,它把这个调用转换成SOAP格式化的XML, 传递SOAP信封,把它嵌在对象中透过网络传递到web 服务器。在web 服务器端,也就是说,重新创建这个对象,完成工作,把已经转换为XML的结果发回来,回来之后,变成对象,再返回给我的客户端。所有这些都是自动的。
事实上,让我们来看一个小的演示。
现在你可以看到这个平台的一些令人不可置信的功能。下面15分钟我将作一些有关.NET的事情。首先, 我将创建一些web service. 然后我将用我的浏览器测试这个web service. 然后我会给这个web service加一些数据访问逻辑。最后我要创建一个丰富的客户端,一个web service的客户前台。最后我要实施这个丰富的客户端应用。
让我们开始。只是先让你们看看,这里绝对没有魔术或者字符串放在这里,我将用我最喜欢的编辑器,Visual Notepad, 然后,尽量简单的写几行代码。现在我启动我的书写板,然后写个Web service的程序在这。
现在我们开始写web service. 我喜欢用一下C#, 然后我把这个类叫做“my service”
现在,我写一个头,告诉ASP.NET, 这个文件包括一个web service. 剩下的文件就简单得像一个通常的C#文件。这里我可以说,用一下system.web.servcie 然后我可以写我的类:publice.class.my.service. 然后我生成一个方法,这个方法是将两个整数相加,然后返回给我结果。这实际上就是我的web service的全部代码。
现在,我唯一需要做的事就是,我需要告诉系统请把这个方法作为一个web service
发布出去,为了做到这一点,在我刚才的时候已经说过,只是简单的在这个方法上加一个web method.
现在我们存起来,并把它叫做demo.asmx. 现在让我们启动浏览器。然我来试试,点击这个web service. 所以我要到localhost/demo/demo.asmx 然后只需要退后,看看什么发生了。
首先,当我点击web 页面,ASP.NET每次都会首先看一下这是不是第一次我点击这个web 页面,它是否编译成IL. 现在发生了什么,首先,我写的类,自动被ASP.NET编译。第二件事,ASP.NET注意到我是从一个浏览器端访问的,是从一个web service的客户端访问的。然后她会为这个web service自动生成一个测试页。现在来看一下测试页。有一个add method在这里,我只需要直接调用这个add method, 通过轻轻点击,然后测试页就会让我输入两个参数,X与Y. 所以让我来输入32 和10,然后我们调用这个方法,这是这个方法就运行了。她计算的结果是42, 然后他自动被作为XML传递后来。
所以web service 很像一个简单的花生壳。
现在让我再回到这个测试页。你会注意到不仅ASP.NET自动弹出这个测试页。并且他还会在我的web service 上做一些分析。来看一看他是否遵守所有互联网上的标准。然后他发现,我没有把web service放到一个XML的命名空间,如果我是一个习惯良好的开发人员应该做这些。接下来,它会建议我应该修正我的代码。然后我说好吧,我只需要拷贝粘贴一点更正就可以了。所以我只是抓取他,然后返回我的web service.然后我粘贴,使得这个web service放到一个命名空间。
现在,现实是通过互联网来做一个简单的数学运算是很没效率的一件事—在大多数情况下,人们可能是通过互联网来取一些数据。但是当我来看人们是如何在他们的应用中来创建数据逻辑时,我会发现她好像来源于两种不同的学校。一种模式是,你会把你的数据当成一个对象。你会有一个客户对象,一个订单对象等等。你从数据库中获得对象,然后你给你的对象生成一个实例,然后你把数据放在那里,然后你在上面操作。
另一种模式,你只是简单的存放这些数据在他的表格中。你知道,今天,它就是记录集。在ADO.NET中它叫做数据集。但基本上,你会认为它是一筐数据。
下面我要演示我们是如何将两种模式都支持的很好。先让我们来看一下把创建数据访问看成是对象的方式。然后,事实上,在我的web service里,我会创建一个数据库连接,然后我把它叫做web service. 然后我把它作为一个对象。
接下来,首先我会粘贴一些东西,省得我来写所有的代码,一个叫做联系人的类,包括一个名字,地址,与电话号码。然后我生成一个web service. 它可以返回一个联系人的列表, 我只是把它粘贴上来。
现在,当然,在现实世界中,你不会只是简单的使用这些对象。他们会生成一个数据库。我只是想显示,web service能够返回一个结构化的数据,并且可以操作他。这里你看到我通过我的调用方法,可以返回一个联系人的阵列的对象。
让我们来试,并且存一下。然后我们回到我们的测试页,我们只是简单刷新一下测试页。然后你看到发生了两件事。首先,ASP.NET发现我的web service文件修改过了,所以他重新编译。她产生了一个新的测试页。在新的测试页里,原来在底端提示的错误信息没有了,因为我修正了丢失了的命名空间,我现在有一个连接,这个连接是到一个我写的附加的方法。Get contacts 方法。然后我试着点击这个连接,因为没有参数,它只是让我简单的点击调用按钮。
这里你可以看到结果已经被格式成很好的XML. 请注意这里,我绝对是什么都没做,它就将联系人的对象转换成一个XML, 这里他是一个联系人的阵列,在这个阵列里,每个联系人都有名字,地址,电话号码。所有这些都是自动完成的。
曾经有些人与我争论,他们希望这个联系人的数据库,每一个联系人不要通过XML元素来传递,最好使用XMl属性来传递。
现在,我们回去,然后加一些指示在这里,来控制产生XML的形式。为了做到这一点,我首先使用:system.xml.serialization 然后在我的对象的域上加一些属性,实际上我们是把XML域转换成属性,而不是元素。在名字上做这些,然后我们做其他的, 我们只需要拷贝,然后粘贴,然后我们把这个对象的地址域转换成adder属性,然后把电话域转换成ID属性。
然后我们存起来。我们回到测试页,然后我们刷新我们的web service的结果,它将重新调用web service. 新的格式出现了。这时,你发现XML的格式奇迹般的从使用属性,转换成了元素。所以你可以看到这个工具给了你超强的控制能力。
现在,另外一个传递数据的方法,或者是应用操作数据的方法,只是生成和返回一个完全的记录集,它基本上反映了一个sql 查询的结果,我们当然也可以在web service里实现。事实上,只需要回去,再让我家一些逻辑在这里。首先,我将加几个使用子句,然后输入进来数据命名空间。然后我们抓一些方法进来,粘贴在这里。这是一个小的方法叫“get data”,它使用一个查询字符串。然后她产生一个连接。她为这个连接生成一个适配器。然后她生成一个新的数据集,然后用执行的结果填充他。
然后我们存起来。然后回到我们的web service. 我们将再次刷新这个测试页。你发现他又一次编译了。我们看到“get data“的方法,然后我们调用他。然后,当然,它需要我们填写查询字符串。然后我们敲入字符串。 我们写:say select * from customers,然后我们安执行键。
现在,我们看到的是sql 查询返回的一个XML格式的查询结果。事实上,如果你往下看这里,你会看到每个表的项,比如说有 客户ID 与名字等等。但在这个XML的开始处有一个描述,描述这些数据的格式。所以这些数据不仅包括实际的纪录, 他也包括一个描述,描述这些纪录的意义。以便于客户端应用理解如何显示这些数据。
然后我们来试一下,创建一个客户端的应用来调用这个web service. 所以我们关上所有的窗口,然后我们启动Visual studio. 让我们生成一个自己的项目。我们将生成一个Visual basic的windows表单应用。然后我们叫他客户端。然后我们的windows表单设计器出现在这里,然后我们试着来做一个客户端的应用来调用我们的web service. 并将数据显示在栅格里。所以我们抓取数据栅格,把它放在我们的表单上。我们在抓一个按钮过来。把它放在我们的表单的小面的角上,试着弄得更整齐一些。好了。
现在,为了调用这个web service, 首先我们加一个引用。在我先前提到过。Visual studio自动完成这些步骤,比如说输入web service的描述文件,并且给web service提供一个代理。所以我们只需要简单的点击右键然后说“add web reference” 在这,我们只是点击我们的web service. localhost/demo/demo.asmx 这里,我们再看一下。服务做好了。我们只是加了一个引用并输入他们。
现在我们可以写一些按钮后台的代码,这里我们写:“dim S as new local host.” 因为我没有改变命名空间,我所引用的命名空间,依然是本机的命名空间。现在你可以看到web service上完成的语句。你可以看到my service对象,存放在本机的命名空间上。这正是我刚才写的服务。所以我只是定义他为一个对象。
现在我可引用我的web service. 然后我所做的是“data grid one.data source”。所以通过我的get data 方法从web service上得到我的数据栅格。现在你可以看到我的任务完成了。她知道要去取一个联系人,一个get data的方法在哪里。实际上,她知道当我点击取数据,它会让我输入一个查询字符串,所以我输入select * from customers, 然后我会取出第一个表,从数据集里出来的第一个表。不象一个记录集, 他提出来的是多个表。我们只是选择第一个返回。
所以两行代码来调用这个web service. 让我们试一下,运行这个应用。当你单击这个按钮。这个结果作为xml格式返回,并且把数据放到了数据栅格里。
现在,当然,你的工作不仅是写一个丰富的客户应用,你还得实施这个丰富的客户应用。我们可以让你很容易的在.NET框架上实施这些应用。实际上,你可以通过在一个web 页上的一个连接来开发你的丰富的客户端应用,我来演示以下如何做到这一点。
首先,我到我的项目里。到我的属性里。然后我改变我的build输出路径,是网站的根路径。所以当我创建时,Visual studio将一个exe拖进我所创建的web服务器的根路径。
所以我们创建, 然后我们再回到visual notepad, 我们将写一些HTML的页,连接到丰富的客户端应用。所以我们启动HTML页。我们把它叫做H1. 以便于我们容易的叫他。然后我们说“点击“然后我们生成一个H 引用到Client.exe, 他坐在web服务器的根目录下,所以点击这里,运行这个聪明的客户端应用。我们把它关上,然后我们存出它,我们就叫他启动HTML.
现在让我们来启动浏览器,然后点击这个页,我们到 localhost/demo/start.html.
在这里,你看到一个web 页,我刚才所写的,连接到我的客户端应用。所以当我点击这里时,所有这些都发生在同一台机器。但当我点击这里,我实际上是下在应用到我本地的机器。在互联网下载缓存区来运行他。
这时应用在运行,我可以点击这个按钮。然后他可以与web service对话。
现在你会问:“好吧,那安全性又是怎么样的?” 实际上,应用是运行在一个沙盒中,他保护你的调用你的web service,而不是来自于相同URL的其他web service. 他不能够在磁盘上生成文件,等等,有一个整套的边界在哪里。为了显示这一特性,我把它关上,然后回到Visual studio 然后,我来试图在我的应用中加多几个按钮。然后我来写一个事件处理器来试图做些坏事。我们不打算做得太坏,所以我们只是在这个服务器的根目录下生成一个文件。所以我们只是简单得说 system.IO.file.create 然后我们试图生成一个log.txt在根目录下。
我们build一下,然后会生成一个新的exe在我们的web服务的根目录下。我们回来,启动我们的web页面。我们再次连接,他会下载一个新的可执行文件。你可以看到我们有了一个新的拷贝,因为我们有两个按钮。我依然调用这个web service. 但当我试图在根目录下生成一个文件,我得到了一个违反安全的警告。你看到,他说应用试图要做些。。。。等等,这是安全政策所不允许的。
现在,有趣的事情是,我可以继续运行,因为它都是通过意外处理来处理的。只是每次当应用试图做些坏事时,他都会被停止。
所以在下面的15分钟里,让我们快速回顾一下,.NET提供给了服务器端,客户端等等的功能。
事实上,.NET的核心原则是客户端,服务器端,服务端都可执政的政策。正像.NET框架为开发应用提供了核心的结构,目的就是这个方向,Visual studio.Net也是一样,提供了完全的开发经验。
在客户端,比如说,Visual studio.NET允许你生成多种不同的客户端应用,例如Windows,表单,正像你们刚才看到的,web 表单,或者是利用移动互联网工具来生成前端的移动设备的应用。
在服务器端,我们提供了为服务器端快速的应用开发。 正如你们所用到的客户端应用开发的技术:通过简单的从工具版上抓取控件, 然后把他们拖放到表单上,现在服务器端也可以做这样的事情,比如抓去一个时间日志,或消息队列,放到一个商务逻辑设计器,然后用可视化的方式来创建你的商务逻辑。
我们在Visual studio里有相当丰富的数据访问能力。我们集成了数据设计器,查询创建器,等等,来完善对.NET企业服务器的支持。
并且,当然,你还看到了visual studio.NET对web service的支持,从web service的整个生命周期,从发现,调用,生成,注册与实施。
现在,给大家近距离得看一下visual studio.NET, 我介绍一下Rob copelan 他是visual basic.NET的产品经理。
Rob Copeland: 早上好。你们今天早上已经看到了很多很好的东西。你们已经看到了用visual studio.NET以及.NET框架创建的一些应用。并且Anders 已经带你们大致浏览了一下框架的强大功能,并且如何利用这些丰富的功能来创建应用。
我今天会花几分钟来看一下,Visual studio.NET 是如何简单的开发那些应用。
我将启动开发环境,并产生一个新的项目。所以我点击新项目。然后她允许我选择我想要生成什么样的项目。
现在,我说,我想生成一个web service,然后返回一些关于书的信息。所以我点击asp.net web service.然后我想,我将调用这个书的服务,然后我点击okay.
Visual studio现在将连接web 服务器,为我生成一个应用的根目录, 把那个文件放在那里,然后我需要为了生成这个web service, 我打开设计视图。
现在,这个设计视图是visual studio.NET的新功能。她可以让我很容易的调用那些我正在开发的一些组件与泪。她与我们平常使用表单,拖拉拽方式很相似,拖拉一个组件,设定他的属性,处理他的事件,不需要写那些所有管道性的代码。我可以集中精力在我的商务逻辑上,我想要的代码由web service自动实现。
现在,Anders给你们演示了如何简单的用XML格式从web service上生成数据,返回数据。 我会演示一个类似的过程,我将使用一些在visual studio开发环境中一些丰富的工具。
我将介绍一个visual Studio.NET的新功能,叫做服务浏览器。这个服务浏览器是一个很好的方法来从服务器端取得资源,然后在此基础上来编程。在这个例子中,有两件事。当我有了数据连接,我就可以访问SQL servers.以及其他类型的数据库,我现在有一个服务列表,现在我只有一个在那里,那就是我自己的机器,但我可以在里面加其他的。
我想做的事情就是,当有些人调用我的web service时,我可以从SQL server上取数据,然后返回结果。
所以如果我展开这个节点,我会看到一个数据库透视图。以及连线与存储过程。如果我扩展这个表,这有一个书的表。这是一个我想用到web service里的表。我可以拖拉拽的方式,拖到设计界面。Visual studio.NETE会自动生成组件,这些组件是我所需要的,从SQL server中取出的数据。
在这个例子中,他生成了两个组件:一个连接,他允许我连接到SQL server 然后在那里执行命令,它叫做数据适配器。一个数据适配器就是用来做这些事情,他把数据从SQL server中取出,然后把它放在我想要的表单中,然后放在一个数据激励。Anders刚刚提到过这个概念。
现在,正如我所说的,这在很多方面都很象表单,除了它真的是一个我所工作的类之外。 但它与表单相似之处,就是我点击这个组件, 然后来到属性窗口并给他们设置属性。所以,例如,也许我不想让我的web service叫做service 1。 他只需要简单的来到属性窗口来更改他的名字。我叫他书服务。
在默认情况下,我所生成的数据适配器,会返回所有数据。我真的不想要那么多纪录。我想让一些人能够告诉我需要有关书的什么信息。
所以我回到属性窗口,我可以点击配置数据适配器连接,然后他会带我到一个向导,向导会带我做这些。她问我什么适配器我想要。这里只有一个,所以我就选择这个默认的。现在她问我我想怎样更新我的数据,以及如何从我的SQL server取数据。按照默认方式,我选择SQL 语句,但我将选择生成一个存储过程以便于我可以依赖于SQL server, 并且我可以得到更好的性能与可扩展性。并且Visual Studio.NET自动为我生成存储过程。
当我点击“下一个”,我们可以看到磨人的选择语句,向导想让我们用它,然而他会返回所有记录,但我真的不象这样。所以,我可以快速点击查询生成器,打开他,ISBN是我想要的,客户将会拿ISBN来查询,然后我会基于所给的ISBN来返回数据。所以我到标准域来写入”equals@ISBN”, 这样它将问我ISBN,