怎么能得到数据?
使用ADO.NET,C#拥有任何通用目的语言设计的最好的数据提取和控制能力。从平面文件到数据库,从XML文档到定制文件格式,你拥有对于怎么样和在哪里存取数据的绝对控制能力。当你主要考虑性能的时候,你甚至可以把数据维护在内存中。下面几部分给出了数据存取能力各类型的讲解。
ADO.NET
微软开发了访问服务器专用对象集(ADO)作为对早期应用于VB和Access的数据存取对象(DAO)技术替代。ADO是更早期的一门叫做ODBC的技术的扩展:ODBC允许你使用相似的接口来存取数据,而不管特定的后端(Back-end)数据存储技术。类似于ODBC,ADO要求对于每种特定的信息存储有一个不同的提供者。不同于ODBC只是对于数据库设计,ADO有一个高层的接口允许你从各种资源提取数据。只要你拥有对于特定数据源的提供者,你就可以使用ADO对象按照几乎相同的方式来读写数据。最后,ADO驱动适用于各种主要的关系数据库,你可以为文件型数据库以及平面文件找到驱动。
ADO.NET是ADO的最新进化版。ADO.NET修正了ADO原有的几个问题,扩展了它的能力,以及把它融入到.NET框架而不是像原来那样作为一个单独的插件(Add-on)。在这本书中,你将会广泛使用ADO.NET来存取关系数据。
XML解析器
有许多开源的或者商业的XML解析器。不同的解析器对于W3C的XML推荐有不同理解程度。和.NET共存的XML解析器甚至与微软最近释放的基于COM的XML解析器,msxml4.dll也有些许不同,但是它对于XML和XSLT的支持很符合W3C推荐。.NET框架广泛的使用XML框架做任何事情,从传递参数给SOAP到对象保留,所以,如果你还不熟悉XML和XSLT过程,在你读完这本书之后你就会了解了。
注意:你可以在这里找到XML标准:http://www.w3.org/XML/。
C#文件/流处理
.NET中新文件和流的处理的处理完全依赖于你在开始C#之前使用什么语言。例如,Java和C++的编程经验不会对.NET的输入/输出(I/O)操作的类和方法产生任何影响,但是经典VB开发者拥有很晦涩的并且极度过时的访问文件的方法。根据你怎么打开文件,有几种非常不同的向文件中写数据的命令。例如,如果你打开了一个文本文件,你可以使用Input函数来读数据,使用Print函数来把一些数据加到文件的后面。相应的,你可以使用Read #和Write #语句。相反的,如果你打开了相同的文件来进行二进制存取,你可以使用Get方法来读数据以及Put方法来写数据。
微软脚本运行时库(Microsoft Scripting Runtime Library)的微软版本包含FileSystemObject,以及一组代表文件和文件夹的对象。当你使用FileSystemObject代开文件时,它会返回一个TextStream目标让你可以用来读写文件。TextStream目标(正如它的名字指出的那样)只可以操作文本文件,而不是二进制或者是随机存取文件,但是它让文件存取非常直观。因为微软设计目标模型来操作像是VBScript和JScript的脚本语言,他们都只能使用变量(Variant),它不像类型目标或者是直接文件存取那样高效;然而,不管怎么样,微软都把它包含在VB6的释放版本中(VB6是一个对于包含到.NET框架的实验)。目标并不是VB运行时的一部分,但是你可以通过在VB中包含一个对于微软脚本运行时的引用来使用它们。如果你以前就是一个使用FileSystemObject来进行文件操作的ASP程序员,你会发现使用.NET方法也非常舒服。最大的不同就是FileSystemObject只能够读写文本文件,然而,C#的I/O能力让它也可以一样的处理二进制文件。
C#,就像是大部分现代语言一样,使用流来读写数据。流通常有两种形式——阅读器(Reader)和书写器(Writer)——但是一些流类(通过继承)提供了读和写的服务。流在.NET框架中无处不在。例如,.NET的System.IO的命名空间(Namespace)包含诸如StreamReader和StreamWriter,BufferedStream,FileStream,BinaryReader和 BinaryWriter,以及StringReader和 StringWriter,等等其他的类。
流的优点是,就像是ADO,他们提取能处理任何其他数据的过程。在选择了适当的Stream类之后,不同的流类之间的读写数据的方法都非常相似。例如,如果你在一个文件中打开FileStream,你可以使用它的Write方法来向文件中写字节。相似的,如果你在一个String对象中打开一个StringWriter流,你可以使用Write方法往字符串中写字符。你不再需要记住几种不同的方法来打开一个文件,相反的,你可以创建一个File对象并且使用它的Open方法来获得适当的Stream类型。对于大部分应用而言,高效的文件存取是非常重要的,网络应用程序也不例外。C#的文件操作支持,流控制加速,以及正则表达式的集成使得大部分I/O操作变得非常直接。
内存存储
不管你准备怎样长期存储数据,你还是很可能有需要把数据缓存到内存中。很明显,你这么做是因为从内存提取数据比从一个硬盘上的平面数据或者是数据库中提取数据快很多倍。相似的,为了最大化性能,经常需要缓存对象到内存中,这样你可以避免对于每次请求都创建和初始化对象。在以前的ASP版本中,你必须用C++或者Delphi写这样的对象。然而,你使用C#创建的对象对于缓存到网络服务器上非常安全。
C#,和ASP.NET一起,提供了很多服务器端缓存的选择。你可以缓存对象,页面,数据库查询结果,甚至是页面的一部分。你可以在一个预定的时间刷新数据,例如每15分钟或者是按照用户要求来做。当不在需要的时候,数据可以从缓存中清除。
你应该怎样包装数据?
不管你怎样存储数据——在内存中,在数据库中,或者是在文件中——你都需要包装数据,格式化它,并且把它发送到客户端来显示或者是在客户端脚本中使用。在网络应用程序中,数据的概念通常是让人疑惑的,因为程序员通常认为代码不同于数据。当然,当代码在执行时,确实是这样的,但是当你创建包含代码的客户端页面时,就不是这样了。在那个例子中,客户端代码是服务器端数据。它不需要在服务器上执行,所以直到代码到达浏览器,它更像是发送到客户端的文字。
在讨论各种类型的你可以发送到客户端浏览器的数据时,我有一个建议。把你发送到浏览器的数据想象成一个单独的文字串。忘记在这些字符中包含的类型数据。你最需要理解的事情是,对于大多数页面,你在发送一个字符串。原因是因为刚开始初级网络程序员非常疑惑什么在哪里发生,尤其是当处理客户端脚本时。因此,把所有的响应想象成字符串会简单些。
发送到客户端的HTML
通常,当写网络应用程序时,你需要发送HTML代码到客户端。即使是高级浏览器都只理解几种文件,例如HTML,CSS,文本,几种图像格式,XML文件,以及脚本。少数高级的浏览器只可以理解HTML和图像格式。大部分浏览器接受插件(Plug-in)来扩展他们可以使用的文件类型,其他的浏览器则不能。因此,你唯一可以依赖浏览器的事情就是他们可以解析和现实HTML 3.2。
注意:对于HTML3.2,我可能说错了,因此我自己没有测试所有的浏览器。然而,网络公司通常把HTML 3.2作为低端标准。
无论如何,你可能忘记发送你自己创建的文件格式到客户端。忘记发送几乎任何类型的对象。除非你使用一种浏览器可以解析的文件格式,否则它是不会被显示的。那并不总是坏的。旧版本的不支持JavaScript的浏览器会忽略掉脚本,如果你把它放在一个HTML注释标签中。例如, IE 3.x和网景 3.x会显示下面代码的警告框,其他浏览器则不会。
<!—“低层”浏览器会忽略的脚本-->
<script language="JavaScript">
alert(“这个浏览器可以运行JavaScript!”);
</script>
一些客户端的非浏览器类型,例如无线设备,使用一种叫做无线标记语言(WML)的特殊的XML类型。这些客户端也不使用JavaScript语言;相反,它们使用JavaScript的一种特殊变体,通常叫做WMLScript。
如果你足够幸运(或者是非常不走运,依赖于你自己的观点)在一个客户端浏览器被IT部门看管的局域网环境内,你可能不会在乎哪个客户端会认出哪种文件类型的讨论。然而,如果你在一个可以提供访问互联网,访问公司外客户端,访问远程合同工,或者是访问不经常使用浏览器的员工的公司工作,这个讨论就很相关了。
W3C’s 最终的HTML的推荐是4.01版本,但是最近,另一个XML的子集,叫做XHTML(可扩展的HTML),已经开始获得广泛应用。W3C使用模块来扩展XHTML,但是最简单的版本使用和HTML相同的标签,就是“结构良好的(Well-formed)”的方法。名词结构良好意味着文档遵循XML语法规则——除了别的之外,所有其实标签都有一个对应的结束标签,所有的属性值都是在引号中,所有的标签都是小写的。相应的,标准HTML能够包含像<p>或者是<br>的标签,属性值不需要在引号中除非他们包含嵌入的空格或者是其他分隔符,并且标签是大小写不敏感的。
通过对你的HTML文件做一些相对小的语法改变,你可以使用XML解析器来读文件的内容。那是主要的优点因为从HTML文件中提取内容是一个费时并且容易出错的过程。做出向XHTML的改变也很重要,你可以使用XSLT处理器来从你的HTML文件中提取数据并且对它进行转换。那为什么这很重要呢?下面是一个场景。
你加入了一个电子商务的网络应用程序来卖花。你有很多包含安排,价格以及邮寄信息的HTML文件。一些文件是对于来自数据库的动态信息的模板。应用程序对于想买花的人包含各种选择,包含安排投递,付款以及订单查询。市场部意识到,随着越来越多人开始使用无线设备,这有一个新的机会来提供让他们在移动中买花的机会。例如:
“呀,星期五晚上,你在离开办公室,你突然意识到这天是你妻子的生日。没问题:访问http://www.buyFlowersForYourWife.com/ 。他们会在30分钟内送到城市的任何地方!哇!太危险了!”
你被要求加入无线市场和商业能力到网站中。也许你想要做的第一件事就是让所有的页面动态化。在这中间,你想要从HTML文件中读物数据并且把它转换为WML数据。但是“正确的”答案是在这中间的某种东西。正确的答案是从一个你能够使用XML解析器阅读的表单中获得数据。最简单的步骤就是重新把数据格式化为XHTML。在这之后,你可以使用XSLT把数据转换成HTML,XHTML,WML,或者是用户喜欢的口味。当然,这将会花一些时间,但是最后的结果是当下次一个新用户出现时,只需要很少的工作,你将是第一个找到解决方案的人,并且所有人都会很高兴。
把XML数据发送到客户端
XML是一个有非常大的影响的但是简单的方法。方法就是:如果你把内容包装到HTML样式的标签,而不是使用像<table>和<h1>的标签,但是使用可以描述内容的标签名称,例如<person>,<employee>,<hotel>,<manufacturer>等等,该怎么办呢?再进一步:一些HTML标签是包含其它标签的块标签。如果你想要使用这种能力而不仅仅是嵌套标签,同时,标签和它们的包含器要被认为是父子关系,该怎么办?简单的说,那就是XML。不同是HTML是一个格式化语言,然而XML是数据描述语言。
XML更罗嗦,但是当你想要系统的提取信息时,它更方便。例如,考虑在HTML文件中的一个表格,如果你想要提取列头和值,你需要解析文件来查找<td>和</td>字符。那本身不难,但是当<td>标签包含其他的HTML标记,这就很难了。比较起来,使用DOM来提取相同的信息很容易。DOM让你使用XPath查询来找到内容——标签的属性或者是文档的“结点(Node)”——并且决定标签和它的孩子,兄弟,或者是父亲节点的关系。DOM也让你使用XSLT来把文档从一种转换到另一种。
SOAP请求/响应
从意识到XML是一个非常强壮的数据描述语言到意识到你可以使用XML描述对象,方法,以及参数是一小步。事实上,这个方法如此简单,所以几乎每个主要的数据库以及商业工具提供者在微软发布SOAP两年之内,都开始采用它。如果你知道一些提供者的竞争关系,那么你就会了解那有多重要。
如果你可以在XML中坚持使用对象和数据,并且使用它描述方法调用以及相关参数,那么你就可以把XML当作一个传输机制来在HTTP中使用远程方法调用来避免在使用二进制数据实现同样功能时会遇到的问题。大部分防火墙会屏蔽二进制数据因为它会包含恶意代码,但是它们允许文字通过。使用平面文字SOAP包,你可以把二进制的表达传输过防火墙。
理解SOAP是一种标准的XML格式来进行远程调用和返回值对你而言是很重要的。除了说它是标准,SOAP根本就没有什么特别的。事实上,在你的应用中,你可以绕开SOAP并且使用一个定制的,更现代的版本——但是如果你那么做,你就不会知道一些.NET的内置优点。
当你创建网络服务工程,.NET框架会接管解析SOAP格式的请求并且以SOAP格式来返回值。
定制数据流
有时,你会有不是适用于标准包的数据处理需求。例如,你可能因为性能原因,你的应用程序必须维护一个一直开放的通道来和服务器通讯。C#有比经典ASP更好的内置的网络通讯存储机制。事实上,你可以使用C#不费太大力气写一个定制的HTTP服务器。System.Net类包含TCPClient,TCPListener以及UDPClient类来封装窗口套接口(Windows Socket)。使用这些类,你可以使用高层的套接口接口来实现定制的数据流应用程序。如果你需要低层的存取,System.Net.Sockets类提供了基本的服务来创建互联网连接。
自己翻译的书(关于ASP.NET),希望对大家有帮助 (十二)
最新推荐文章于 2024-09-09 22:16:15 发布