ASP.NET.2.0.in.C.Sharp.2005.From.Novice.to.Professional的读书笔记[9]

来源:互联网 发布:unity3d 漫游展示 编辑:程序博客网 时间:2024/04/29 05:11

CHAPTER 5  Web Form Fundamentals

ASP.NET介绍了创建网页的值得注意的一种新模式.在老模式的ASP开发中,编程者在开发一个动态页面之前,必须精通HTML的标志的细节和规则,页面的设计是一个细致裁剪的任务,而且额外内容的产生只能输出由HTML标签组成的.

在ASP.NET,你可以使用更高级别的模式的服务端web控件.这些控件是作为对象被创建和配置的,而且自动提供他们的HTML输出.更好的是,ASP.NET允许WEB控件可以象桌面应用程序一样,有自己的状态,甚至有自己的事件.

在此章中,你会学到ASP.NET开发者所需要精通的核心内容,什么是一个ASP.NET应用程序的标记,什么文件类型是可以被包含的,服务端控件是如何工作的,你如何使用他们创建一个动态的页面.

The Anatomy of an ASP.NET Application

有时很难定义WEB应用程序到底是什么.与传统的桌面应用程序不同的是,ASP.NET的应用程序被分成了多个页面.这个分类意味着一个用户可以通过多个渠道进入ASP.NET应用程序,通过link等.所以,认为网站是一个应用程序是明智的吗?

在ASP.NET中,答案是肯定的.每个ASP.NET程序共享一个通用的资源和配置设置.其他ASP.NET应用程序的页面不共享这些资源.就技术而言,每个ASP.NET应用程序是在他自己的应用程序域中执行的.应用程序域内存中一个独立的区域,即使是他产生了错误,他也不可能影响到在服务器上运行的其他程序.同样,应用程序域限制一个程序的页面访问内存中另一个程序的页面.每个WEB应用程序是相对独立的,有他们自己的缓存,应用程序和session数据.

ASP.NET应用程序标准的定义是,它是文件,页面,HANDLER,模块,可执行代码的混合物,他们被包含在服务器的虚拟目录上.换言之,虚拟目录是WEB应用程序基础的组成结构.

ASP.NET File Types

Ends with .aspx,Ends with .ascx,Ends with .asmx,web.config,global.asax,Ends with .cs.
ASPX是界面.ASCX用户控件,ASMX网页服务,web.config一个基于XML的配置文件,global.asax定义一个全局变量的位置,CS包含C#语言的内部代码.

除此之外,你的WEB应用程序可以包含其他的资源.例如,你的虚拟目力可以发布image文件,HTML文件,或CSS文件.这些资源可以使用在某一个页面上,或者单独的使用.

大部分的文件类型是可选择的.你可以使用只有一个页面的.aspx file或.asmx file创建ASP.NET应用程序.

ASP.NET Application Directories

每一个WEB应用程序应该有一个计划好的目录结构.例如,你需要把图片和页面存储在不同的目录中.或者,你想放置发布的ASP.NET页面在另一个文件夹中,限制其他的以便在目录的基础上应用不同的安全设置.

随着目录的建立,ASP.NET同样使用一些由名字识别的特殊目录,但需要知道的是,你不会在典型的应用程序中看见所有这些目录.VS会在需要的时候迅速的建立他们.

Application Updates

ASP.NET最有用的特性之一是与新的控件或增强的功能没有关系的.因此,它被称为零接触配置和应用程序更新,意味着你可以简单轻松的改变ASP.NET应用程序而不需要重起服务器.

Page Updates

如果你改变了代码文件,或者WEB FORM,ASP.NET会为下个客户端的请求自动重编译一个新的版本.这是说,新的客户端请求总是使用最近的页面的版本.ASP.NET甚至自动编译页面到本地机器代码中,缓存它以得到改进.

Component Updates

你可以放置任何编译文件的新版本在BIN目录下,.这个文件将永远不会被锁上.因此,你可以随意添加或删除编译文件.ASP.NET不停的监视BIN目录下的改变.当某个改变被发现时,它创造一个新的应用程序域,使用它来处理任何新的请求.存在的请求会由老的域来完成,当所有存在的请求全部运行完了之后,老的域就会从内存中清除掉.

这个自动转滚特性,由时候称之为shadow copy,允许你在不关闭的情况下,无故障的更新网站.

Configuration Changes

在早期的ASP程序中,配置一个WEB应用程序不是一个简单的工作.你需要创建一个脚本,这个脚本用来改变IIS的METABASE或者使用IIS MANAGER.一旦改变发生,你通常需要重起IIS的WEB SERVICE.有时你甚至需要重起服务器才能使得设置生效.

幸运的是,这些在ASP.NET中都将不在存在了,ASP.NET的配置文件存在于WEB.CONFIG中.这个文件可以轻易的被编辑.如果改变了WEB.CONFIG设置,ASP.NET使用自动滚转的方式更新它.

A Simple One-Page Applet

你将看到的第一个例子是,服务端控件是如何在一个简单的页面程序中工作的.这个例子的功能是将美圆转换成等值的欧圆.

这块是实际动手的操作了,略过.动手去了!!!

The ASP Solution—and Its Problems

这个程序在以前是非常的麻烦的,但在ASP.NET中却没有.

The ASP.NET Solution: Server Controls

ASP.NET提供了两种服务端控件:

HTML服务端控件和ASP.NET服务端控件.

HTML Server Controls

HTML服务控件提供了HTML部件的对象表现。他们提供了三个特性:

他们有自己的表现:在代码中设置属性,HTML会自动的更新.
他们保留了自己的状态:因为网页是无状态的,通常的页面需要花大量的工作存储请求的信息.例如,每次用户点一个按钮,你都需要确认页面上的每个按钮都是被刷新过了的,这样用户看到的是最近的信息.ASP.NET,这种沉闷的工作远离了你.这意味着你可以象开发传统的WINDOUS程序一样开发你的工程.
他们的事件:你的代码要对这些事件做出响应,就象WINDOWS应用程序中普通的控件一样.在ASP代码中,所有的东西被包含在一个块中,只开始执行到结束.在基于事件的程序中,你可以响应独立的用户事件,而且还可以创造更多的结构代码.如果一个给定的时间没有发生,event handler不会执行.

最简单的转换货币转换器到ASP.NET的方法是,在VS中以一个新的WEBFORM开始.这样做,选择,WEBSITE>ADD NEW ITEM.在加入新项的对话框中,选择WEBFORM,为新的页面输入一个名字,然后OK创建页面.最后,COPY在普通HTML页面中的内容到新的ASP.NET的WEBFORM中去.

当你粘贴HTML内容的时候,这会覆盖除指令所有在此页面中的内容.页面指令给ASP.NET提供关于编译页面的基本信息.他指出你编写所使用的语言和你连接到event handlers的方式.如果你使用建议的代码隐藏方式,页面指令同样会指出代码文件的位置和你的页面类的名字.

现在你需要加入 runat="server" 的标志到每个你想要转换成服务端控件的标签,你同样需要添加id标签到每个控件,这些控件与你的代码相互影响.ID标志显示唯一的名字,在代码编写中将用到.

在货币转换应用程序中,你可以改变input text box and submit button到服务端控件.这样<FORM>部件必须被按照服务端控件执行,允许ASP.NET访问他包含的控件.代码如下:

目前页面还不能做任何事,因为你还没有写任何的代码.尽管如此,你已经将HTML部件转换成了HTML服务端控件,你已经在使用他们了.

View State

要尝试这个页面,在VS中运行它.选择VIEW>SOURCE在你的浏览器中查看ASP.NET发送给你HTML的方式.

你首先需要注意的是,你会注意到发送给你的HTML与aspx文件的信息有细微的差别.首先,runat="server" 标志是strip out的.其次,更重要的是,额外的隐藏区域被加入到了FORM.代码如下.

这个隐藏的区域以被压缩的形式存储信息,这些信息是关于每个控件的状态的.它允许你操作处理到吗中控件属性和有被自动坚持的改变.这是WEBFORM程序模式的关键部分.多谢view state,你可以忘记INTERNET特性细微的状态,然后继续运行你应用程序.

甚至货币转换器不包含任何的代码,你会注意到一个改变.如果你在text box中输入信息,然后点击submit button发送页面,更新页面会依然包含你所输入的数值.(在传统的HTML网页中,数值在每次回送的过程中会被清除.)这个改变发生是因为ASP.NET控件自动保留了状态.

The HTML Control Classes

在货币转换器进行高级步骤之前,你需要了解这些创建的控件对象.所有的HTML服务端控件都在System.Web.UI.HtmlControls中有定义.每个种类的控件有不同的类.表5-3描述了基本的服务端控件,说明了与HTML部件之间的关系.

目前为止,货币转换器定义了三个控件,这三个控件分别是HTMLFROM,HtmlInputText,HtmlInputButton类的及时(instance)方法.知道类的名字是非常的重要的,因为如果你想与他发生联系,就需要在代码编辑文件中定义每个控件的类.

要使得货币转换器有一定的功效,需要加入一些ASP.NET代码.WEBFORM是事件驱动的,这意味代码的每个片断都与某一个事件相互反应.在此页面中,最有用的事件是,当用户点submit button时,需要发生的事件. HtmlInputButton可以通过ServerClick事件响应这个动作.

在继续之前,很明显需要加入另一个控件,此控件能够显示计算出来的结果.这样,你要使用一个名字为Resulut的<div>标签.<div>标签是插入一个格式化的文本的一种方法.

样式标签应用于CSS属性,CSS是用来格式化文本的.

Event Handling

 此例子使用了一种叫做事件自动挂钩的技术.要使用此技术,你要在标签中使用一个标志来连接到你的event handler.

例如,如果你想连接Convert按钮的ServerClick方法,你只需要在控件标签中简单的设置OnServerClick标志.形式如.OnServerClick="Convert_ServerClick".

ASP.NET控件总是使用这种方式来挂钩事件.当你在VS中双击一个控件,这种改变是自动生成的,不需要手动去输入.
ASP.NET还有一种技术,叫手动事件挂钩,使用这种方式,所有的事件钩子被连接到代码和用户的委派,就象第三节讲的一样.
既然有了自动挂钩为什么还有保留手动挂钩呢?因为手动挂钩在某些情形下是非常有用的.例如你想在一个页面动态运行的时候加入一个控件对象,在这种情况下,你不可能通过通过控件标签加入事件钩子,因为根本就没有控件标签.你必须自己创造控件然后使用代码将它与事件钩子挂钩.

Behind the Scenes with the CurrencyConverter

因此,当ASP.NET收到CurrencyConverter.aspx页面请求的时候,什么会真的发生.进程实际上按照以下步骤进行:
*首先,页面的请求被发送到WEB服务器.
*WEB服务器检查ASPX文件时候在ASP.NET中注册,然后将请求传递给ASP.NET工作进程.如果文件属于另一个服务,ASP.NET不会做任何事情.
*如果这个页面是第一次被请求.ASP.NET自动创建程序域,和一个特殊对象.
*ASP.NET检查特定的ASPX文件.如果他从来没有被执行过,那么ASP.NET编译且缓存页面到c:/[WinDir/Microsoft.NET/Framework/[Version]/Temporary ASP.NET Files中,如果已被执行过且文件没有被修改,那么ASP.NET会使用已编译好的版本.
*被编译的CurrencyConverter就象一个小程序.它以事件开始.但是你并没有创建事件执行体到此事件,所以没有代码被执行.在此平台上,所有的东西都作为.NET对象在内存中一起运行.
*当代码结束后,ASP.NET检查每个控件将他们转换成对应的HTML语句.
*最后页面被发送给用户,程序完毕.

Improving the Currency Converter

Adding Multiple Currencies

制作一个可以让用户选择目标货币的页面.在此需要用到下拉菜单.在HTML中,下拉菜单的标签是<select>.
在currency下拉菜单中实时的添加项目.在Page.Load事件中使用,Currency.Items.Add(new ListItem("Euro","0.85"));语句就可以实时的添加项目了.this.IsPostBack 获取一个值,该值指示该页是否正为响应客户端回发而加载,或者它是否正被首次加载和访问。如果是为响应客户端回发而加载该页,则为 true;否则为 false。Page.IsPostBack属性,只有在页面第一次执行时的值为false,所以如果你这样写的话
if(!IsPostBack)
{
TextBox.text=".........";
}
那么条件内的代码在页面第一次加载时执行。想在页面第一次加载时初始化页面的变量,数据,控件等,而不是每次页面提交时都初始化这些值,可以用这个属性。
你以上所说,页面执行完Page_Load事件,加载完成后,IsPostBack的值就是true了。
点击按钮再次向服务器请求,第二次页面加载Page_Load事件if(!IsPostBack)条件下的代码不会再执行。试一下下面的代码就会看出效果不同了。

Storing Information in the List

在列表中存储信息.如果我们在下拉菜单中存储转换率的信息会使得程序变得很方便.在这里要使用到ListItem类.此类就可以同时存储列表名以及对应的数值.Currency.Items.Add(new ListItem("Euro","0.85"));.ListItem (String, String)  用指定的文本和值数据初始化 ListItem 类的新实例.
public ListItem (
 string text,
 string value
)
text要在列表控件中为 ListItem 所表示的项显示的文本。value与 ListItem 关联的值。
Currency.SelectedIndex获取或设置 HtmlSelect 控件中的选定项的序号索引。

Adding Linked Images

添加一个按钮,当选择货币时输出相应的图片.这里和上面异曲同工.不再多说了.

Setting Styles

每个HTML控件可以通过Style collection对CSS样式标签进行访问.要使用这个collection,语法是:ControlName.Style["AttributeName"]="AttributeValue";例如,你可以使用这种技术拉加强对程序的控制,如果输入的是负数,就将Result控件变成红色.在这种情况下,在输入正确的时候,你同时还需要重设到默认的颜色,因为控件使用的view state会记住所有对它的设置,这些设置包括了样式属性.

这个例子也存在问题,就是当输入非数字形值的时候会产生错误.解决这个问题的方法在第七章中讲解.
在这个程序中我们实现了,自动计算,连接图片,动态格式等.

自己研究的,如果想在输入数字之后按回车就可以计算的话,需要在US_ServerChange事件中加入Convert_ServerClick(sender,e)这样就可以了.

A Deeper Look at HTML Control Classes

在.NET FRAMEWORK中相关的类使用继承来共享函数.例如,每个HTML控件是从HtmlControl基类中继承而来的.HtmlControl类为每个HTML服务端控件提供了实用的特性.5-7显示的就是继承表.

下面的部分是分析被用于HTML服务端控件的ASP.NET类.要知道HTML控件的细节问题,你可以查看MSDN.

HTML服务端控件的属性与它在代码文件中的标签是非常相近的.例如,HtmlImage类有Align, Alt, Border, Src, Height, and Width等属性.因此,对HTML熟悉的人而言,这些语法是很简单的.对于不太懂HTML的自然会发现WEB控件有着很直观的一些属性.

HTML Control Events

HTML控件提供了两种可能的事件,ServerClick 和 ServerChange,这两个事件在一个控件中最多有一个,要么是ServerClick,要么是serverChange,ServerClick事件是一个服务端的点击事件.在几乎所有的按钮控件中都有,允许代码对它立即做出反应.这个事件可能不会达到预期的效果.例如,如果截取一个超连接控件的点击事件,用户不会重定向到一个新页面,除非你提供一个额外代码去相应请求.

ServerChange是对应于一个文本或选项被改变时而产生的事件.这个事件并不那么容易使用,因为当页面回传给服务器的时候,这个事件才发生.在此点上,ServerChange事件是对于所有被改变的控件的.Page.Load事件是最先被运行的,但是你并不知道其他控件的事件.

Advanced Events with the HtmlInputImage Control

 

第四节介绍了事件的标准结构,每个事件都要接受两个参数,第一个参数是被事件挂钩的对象.第二个是一个可以包含事件额外信息的特殊对象.

在目前已有的例子中,第二个参数总是被传递了一个空的System.EventArgs对象.这个对象没有包含信息.

实际上,只有一个HTML服务端控件发送额外信息:HtmlInputImage控件.它发送一个ImageClickEventArgs对象,它提供了X和Y坐标,这个坐标是IMAGE被点击的坐标.你会注意到, HtmlInputImage.ServerClick event handler的定义与其他的事件handler有所不同:protected void ImgButton_ServerClick(object sender,ImageClickEventArgs e).下面则是实际这个功能的代码.动手操作一下.

The HtmlControl Base Class

每个HTML控件都是继承HTMLCONTROL基类的.这种关系意味着每个HTML控件都有着一组基础的属性.他们是,Attributes,Controls,Disabled,EnableViewState,Page,Parent,Style,TagNameVisible,HTMLCONTROL类也提供内建的数据绑定.

The HtmlContainerControl Class

HTML容器控件他们可以包含其他的HTML部件,例如<a>,<form>,<div>.另外,<img>,<input>,就不能包含其他的控件.HtmlContainer控件多了两个属性,innerhtml,INNERTEXT.

The HtmlInputControl Class

他们都有着一个<input>标签,如<input type="text">,<input type="submit">,<input type="file">.他们的属性多了两个,Type,Value.

The Page Class

Page类我们没有细致的讨论.如前面章节所解释的,每个WEB页面是一个继承System.Web.UI.Page的类.继承了System.Web.UI.Page类,你的页面获得了一系列的属性.这些属性包括enabling caching, validation, and tracing,他们是我们需要讨论的.一些更基础的属性,包括ASP开发者经常使用的传统的内建对象,如,Response, Request, and Session.这些更基础的属性是Application and Session,CacheControls,EnableViewState,IsPostBack,Request,Response,Server,User.

The Controls Collection

Page.Controls collection包含了页面上所有的控件.可以通过此收集并访问每个控件.紧接着的代码将页面的每个控件的名字写在Result这个控件上.
同样我们可以使用Controls collection来添加一个动态的控件.下面的代码创建了一个新按钮,将之添加到页面的底部,这个按钮是动态的.

产生新按钮最好的地方是在Page.Load事件的执行体中.它可以确保控件会在每次页面被运行的时候创建.另外,如果加入一个使用view state的input控件,那么view state的信息会在Page.Load事件执行完之后存储在控件中.这意味着一个动态生成的文本框将包含它的文本在多次回传之后,就象一个文本框被定义在ASPX文件中一样是没有区别的.动态生成的控件是很难被定位的.默认的情况下,都是在页面的底部.唯一改变的方法是,创建一个容器控件,例如服务端的<div>,然后你可以将动态生成的控件添加到里面了.

The HttpRequest Class

HttpRequest类封装了所有与WEB连接请求有关的信息.大部分的信息涉及到低级的细节,如posted-back form values, server variables, the response encoding,等等.如果使用ASP.NET,我们永远不会涉及到那层.其他的属性对于检取信息是很有用的,特别是关于连接浏览器的权限.通常使用最频繁的是ApplicationPath and PhysicalPath,Browser,ClientCertificate,Cookies,Headers and ServerVariables,IsAuthenticated and IsSecureConnection,QueryString,Url and UrlReferrer,UserAgent,UserHostAddress and
UserHostName,UserLanguages.

The HttpResponse Class

HttpResponse类可以直接向客户端发送信息.在传统的ASP开发中,Response对象对于创建动态页面是非常的重要的.现在,通过介绍了服务端控件,这些方法不再需要了.

HttpResponse提供了一些重要的应用,例如,caching support, cookie features, and the Redirect method.HttpResponse的成员有,BufferOutput,Cache,Cookies,Write(), BinaryWrite(), and WriteFile(),Redirect().

The ServerUtility Class

ServerUtility类提供了多样的帮助方法.

CreateObject(),HtmlEncode() and HtmlDecode(),UrlEncode() and UrlDecode(),MapPath(),Transfer().

在这些方法中,使用得最多的是UrlEncode()/UrlDecode() and HtmlEncode()/HtmlDecode().这些函数将字符串转换成表达式,这个表达式能安全的被用做,URL的一部分和显示一个页面.例如:

假设我们要显示这个文本:Enter a word <here>,如果在页面中写入这个信息,那么你只会看到Enter a word,因为浏览器会把<here>看成是一个HTML标签.相似的是,如果使用的是一个可用的HTML标签同样也会出问题.To bold text use the <b> tag.<b>是不会显示出来,同时浏览器将把它之后的字变成粗体.

要解决这个问题有三个方法
*Enter a word &lt;here&lt;
*使用控件的InnerText属性.
*使用Server.HtmlEncode("Enter a word <here>").

空格对应的是&nbsp;        <是&lt;     >是&gt;       &是&amp;     "是&quot;   

ASP.NET Configuration

每个WEB服务是由一些基本设置开始的,这些基本设置存放于两个文件中,这两个文件是machine.config和web.config.一般而言,这两个文件你是不需要去管它的.在你的WEB应用程序中有一个web.config文件,使用这个文件,可以加入一些额外的设置或不管在别处定义的默认设置.

.config文件比传统的ASP配置有着许多优点:

They are never locked:在任何时候都可以更新web.config设置,ASP.NET可以平稳的将之转移到新的应用程序中.
They are easily accessed and replicated:假设,你有适当的网络权限,你可以从远程计算机更改WEB.CONFIG文件.同样你也可以复制它.
The settings are easy to edit and understand: web.config文件是很容易读懂的.

The web.config File

WEB.CONFIG文件使用了一种预处理XML格式.全部的内容是被放置在<configuration>与</configuration>中,在它之中又有<system.web>,这个是为ASP.NET设置准备的.在<system.web>中就是各个想要的设置了.注释是放在 <!-- and --> 之间的.

可以添加任意多的配置部分.例如,如果想指定特定错误的设置,你只需添加<customError>单元,需要注意的是WEB.CONFIG是大小写敏感的,就象所有的XML文档一样,所有的设置都以小写为首字符.

如果想大致了解所有可用的设置,到c:/[WinDir]/Microsoft.NET/Framework/[Version]/Config文件夹中,然后查看WEB.CONFIG.COMMENTS文件.这个文件由XML注释组成,这些注释说明了每个可能的设置可用的选项.同样你也可以在MSDN中搜索他们.

Nested Configuration

ASP.NET使用了一个多层次的配置系统,这样就可以对不同的程序部分使用不同的设置.要使用这个技术,首先要在你的虚拟文件夹中创建额外的子目录.这些子目录包含了使用额外配置的WEB.CONFIG文件.

子目录从父目录中继承了WEB.CONFIG设置,例如,假想你在c:/ASP.NET/TestWeb中创建了一个站点,在c:/ASP.NET/TestWeb/Secure文件夹中,创建一个名为Secure.Pages的文件夹,设置可以从三个文件中获得,图5-10,大意是说,文件夹中的配置文件只对此文件夹中的文件有效.

Storing Custom Settings in the web.config File

在<appSettings>中可以使用自己想要的设置.需要注意的是<appSettings>要放在根<configuration>中而不是<system.web>中.
用户自定义的设置是写成简单的字符串变量的.或许你因为某些原因需要使用WEB.CONFIG设置.

To centralize an important setting that needs to be used in many different pages:例如,我们可以创建一个存储数据库查询的变量,任何需要使用这个查询的页面都可以使用它.

To make it easy to quickly switch between different modes of operation:例如,或许我们需要创建一个调试变量,页面检查这个变量,如果它被设置成一个特殊的值,就会输出额外的信息,这些信息可以帮助我们测试程序.

To set some initial values:依据操作,用户可能会修改这些值,但WEB.CONFIG提供了默认值.

使用<add>标签可以定义一个唯一的变量名(key)和变量内容(value).下面的例子添加了两个特殊的变量,一个包含了数据库连接字符串,另一个定义了适当的获取销售记录的SQL状态.

我们可以创建一个简单的测试页去查询这个信息,然后显示结果.从WEB.CONFIG文件中使用key关键字获得的自定义的程序设置,使用WebConfigurationManager类.这个类提供了一个名为AppSettings静态的属性."动手操作一下"

有人或许会问把SQL密码放在此文件中安全吗?我们可以尝试去访问WEB.CONFIG文件,可以发现此类文件是不能被远程用户所访问,他们会收到错误的信息.

Modifying web.config Settings Programmatically

改变所需要的花费是很大的,所以当改变设置的时候,ASP.NET会生成一个新的页面,但这会导致浏览速度非常的慢,因此不要在CONFIG文件中存入会经常改变的数据.要改变设置,首先使用WebConfigurionManager.OpenWebConfiguration()方法获得一个Configuration对象.然后可以使用这个对象去读写值.当你改变完成之后,使用Configuration.Save()保存修改.手动操作一下.
需要注意的是,OpenWebConfiguration()需要一个路径.这个路径就是你想要修改配置文件的路径.

The Website Administration Tool (WAT)

Website>ASP.NET Configuration.就可以运行WAT了,在这个里面可以进行添加,修改,删除操作.这个工具可以说是非常的不错的一个工具.以后再不需要手动输入那些值,而完全可以自动的输入他们了.

原创粉丝点击