Essential.ASP.Dot.Net.With.Examples.In.C.Sharp.eBook-LiB.
http://www.readol.net/books/computer/dotnet/Essential.ASP.Dot.Net.With.Examples.In.C.Sharp/
ASP.NET 基础教程-C#案例版
一,Architecture架构
1,基础运行架构:是基于类的三层结构
(1)客户端请求
(2) asp.net工作者进程(worker process):是从IIS5.0的inetinfo.exe中分离出来的独立的aspnet_wp.exe(IIS6.0中则为w3wp.exe),所以可以脱离IIS,如使用cassini在apache下运行.net。
(3)三种.net类:
system assemblies:系统组件/程序集,指基础类库在.net运行时加载的类
global assembly cache (GAC):全局组件/程序集缓存,指供全局使用的类
local assemblies:本地组件/程序集,指由本地虚拟目录中程序加载的类
图1-1, asp.net的概要架构
Figure 1-1. High-Level Architecture of ASP.NET
2,.net与asp
.net采用编译方式运行,在首次加载.aspx页面时(做了三个工作,一是加载.net工作者进程,二是分析.aspx页面,三是编译.aspx页面为程序集assemblies)比asp还要慢,但之后再加载任何相关.aspx页面就无需再次编译,直接高效运行。
asp采用解释方式运行,每次加载asp页面,都先进行线性分析,然后把服务器端代码一一交给JScrip/VBScript引擎去解释运行,最后把服务器端代码执行结果和非服务器端代码混合起来一起响应给客户端。即使是采用了com封装组件和response输出静态代码等方法,也无法从根本上提高运行效率。
3,System.Web.UI.Page基类
大部分的.aspx类都以它为基类,所以了解它的成员,属性与方法就如此重要。
Listing 1-3 Important Members of System.Web.UI.Page
public class Page : TemplateControl, IHttpHandler4, code-behind(代码隐藏)技术
{
// State management状态管理工具
public HttpApplicationState Application {get;}
public virtual HttpSessionState Session { get;}
public Cache Cache {get;}
// Intrinsics根本功能
public HttpRequest Request {get;}
public HttpResponse Response {get;}
public HttpServerUtility Server {get;}
public string MapPath(string virtualPath);
// Client information客户端信息
public ClientTarget ClientTarget {get; set;}
public IPrincipal User {get;}
// Core核心控制功能
public UserControl LoadControl(string virtualPath);
public virtual ControlCollection Controls {get;}
public override string ID { get; set;}
public bool IsPostBack {get;}
protected void
RenderControl(HtmlTextWriter writer);
//...
}
(1)产生背景:注意在.aspx页面中,处于服务器端脚本块标记<script runat=server></script>中的代码,在编译后会被直接放到类定义中。而处于服务器端脚本标签<% %>中的代码,在编译后会被放在函数中,去调用和执行类。
如此一来,想要正确迁移到.net的asp程序,就不能在<script runat=server></script>中定义的函数的作用域之外放入可执行代码,也不能在<% %>放入函数定义。
另外,.aspx编译后机器会自动生成默认的构造函数。如果你试图自定义该函数就会产生编译错误。而且你如果想正确初始化你的类的元素,如给数组赋值或订阅事件,也会失败。
Figure 1-3.服务器端脚本被编译后的不同位置 Server-Side Code Placement in Page Compilation
因此, .net发展了code-behind(代码隐藏)技术,来分离页面与代码,并加强对类的控制。
(2)使用Code-Behind:Code-Behind会创建一个中间(ntermediate)基类,该类往上直接继承page基类,然后只要在.aspx文件中使用Page指令的Inherits/Src等属性,就能往下被.aspx页面编译成的类继承。
Listing 1-5 Sample .aspx File Using Code-Behind
<!— Codebehind.aspx —>
<%@ Page Language="C#"
Inherits="EssentialAspDotNet.Architecture.SamplePage"%>
<html><body>
<h2>aspx==class!</h2>
<ul>
<% WriteArray(); %>
</ul>
</body> </html>
Listing 1-6 Sample Code-Behind File
// SampleCodeBehind.cs
using System;
using System.Web;
using System.Web.UI;
using System.Collections;
namespace EssentialAspDotNet.Architecture
{
public class SamplePage : Page
{
private ArrayList _values = new ArrayList();
public SamplePage()
{
_values.Add("v1");
_values.Add("v2");
_values.Add("v3");
_values.Add("v4");
}
protected void WriteArray()
{
for (int i=0; i<_values.Count; i++)
Response.Output.Write("<li>{0}</li>",
_values[i]);
}
}
}
如此一来,我们就可以自定义类的构造函数,并成功初始化。
所有的Code-behind类(中间基类)必须被编译成程序集,放在/bin目录下,以备编译程序引用。
Figure 1-4. Code-behind技术下的类继承关系
Class Hierarchy Created Using Code-Behind
你还可以使用Src属性直接指定Code-Behind基类的引用文件。这样就把编译Code-Behind基类的编译过程独立开来。你可以直接物理更新Code-Behind基类的引用文件而不需编译就达到系统会自动更新Code-Behind基类的目的。但同时也有错过手动编译而漏过编译错误的危险。
Listing 1-7 Using the src Attribute to Reference a Code-Behind File
<!— Codebehind.aspx —>
<%@ Page Language="C#" src="SampleCodeBehind.cs"
Inherits="EssentialAspDotNet.Architecture.SamplePage"%>
<!— ... —>
(3),控制Page基类的事件发布:
用Code-Behind技术来控制Page基类的事件发布,这样就能在.aspx中不另外添加代码就控制响应页面的生成。
Page如下定义了四个事件,它们都是从Contrl基类中继承而来的。
Listing 1-8 Events Defined in System.Web.UI.Page
public class Page : TemplateControl, IHttpHandler你可以通过三种方式注册对上述事件的处理函数,前两种方式无优劣之分,只有流程之别。
{
// Events
public event EventHandler Init; //系统恢复初始化状态之前
public event EventHandler Load; //系统恢复初始化状态之后,事件激发之前
public event EventHandler PreRender; //事件激发之后,生成响应文件之前
public event EventHandler Unload; //生成响应文件之后
// Predefined event handlers
protected virtual void OnInit(EventArgs e);
protected virtual void OnLoad(EventArgs e);
protected virtual void OnPreRender(EventArgs e);
protected virtual void OnUnload(EventArgs e);
}
首先是直接重写:可以直接重写page基类中定义的虚函数,完成事件处理。
也可以手工订阅:先重写page基类中定义的虚函数,在其中手动订阅一个委托,调用委托完成事件处理。如下:
Listing 1-9 Trapping Page Events in Code-Behind
// File: EventsPage.cs第三种订阅Page事件的方法是自动绑定AutoEventWireup,就是在系统打开AutoEventWireup(Page的 AutoEventWireup属性为true)的前提下,只要在 Page_Init, Page_Load, Page_PreRender, or Page_Unload四个Page派生函数中添加方法和 EventHandler委托所需的签名。由于上述四个函数在Page派生类创建时会被自动使用Reflection搜获并初始化,就可以订阅该事件。
public class EventsPage : Page
{
// Override OnInit virtual function to manually
// subscribe a delegate to the Load event
protected override void OnInit(EventArgs e)
{
this.Load += new EventHandler(MyLoadHandler);
}
// Load event handler
protected void MyLoadHandler(object src, EventArgs e)
{
Response.Write("<tiny>rendered at top of page</tiny>");
}
}
但该方法由于在执行时多了一个环节,需要runtime type information去查找相关方法与订阅,所以效率较低,所以在不使用上述方法时可以如下通过设置Page的AutoEventWireup属性为 False,以禁用runtime type information查找。
Listing 1-11 Disabling AutoEventWireup
<%@ Page Language='C#' AutoEventWireup='false' %>
<!— ... —>
6,影子复制和动态生成目录:实现Xcopy部署功能。
AppDomainSetup类(用于初始化AppDomain类) 对外提供以下属性:
ShadowCopyFiles:Boolean类型,是否启用影子复制功能
CachePath:string类型,指定影子副本的基目录
DynamicBase:指定动态目录
AppDomain类对外提供一个方法SetShadowCopyPath():指定可用于影子复制的目录
Figure 1-5. Shadow Copy Mechanism Used by ASP.NET
Figure 1-6. Dynamic Base Directory Used by ASP.NET
6,指令:
Directive Name |
Attributes |
Description |
---|---|---|
@Page |
See Table 1-2 |
Top-level page directive |
@Import |
Namespace |
Imports a namespace to a page (similar to the using keyword in C#) |
@Assembly |
Name Src |
Links an assembly to the current page when it is compiled (using src implicitly compiles the file into an assembly first) |
@OutputCache |
Duration Location VaryByCustom VaryByHeader VaryByParam VaryByControl |
Controls output caching for a page (see Chapter 9 for more details) |
@Register |
Tagprefix Namespace Assembly Src Tagname |
Registers a control for use within a page (see Chapter 8 for more details) |
@Implements |
Interface |
Adds the specified interface to the list of implemented interfaces for this page |
@Reference |
Page Control |
Specifies a page or user control that this page should dynamically compile and link to at runtime |
Listing 1-14 Source File for TempConverter Component
// File: TempConverter.cs
using System;
using System.Reflection;
[assembly : AssemblyKeyFile("pubpriv.snk")]
[assembly : AssemblyVersion("1.0.0.0")]
namespace EssentialAspDotNet.Architecture
{
public class TempConverter
{
static public double FahrenheitToCentigrade(double val)
{
return ((val-32)/9)*5;
}
static public double CentigradeToFahrenheit(double val)
{
return (val*9)/5+32;
}
}
}
Listing 1-15 Sample .aspx Page Using the TempConverter Component
<!— TempConverter.aspx —>
<%@ Page Language='C#' %>
<%@ Assembly Name="TempConverter, Version=1.0.0.0,
Culture=Neutral,PublicKeyToken=a3494cd4f38077bf" %>
<%@ Import Namespace="EssentialAspDotNet.Architecture" %>
<html>
<body>
<h2>32deg F =
<%=TempConverter.FahrenheitToCentigrade(32)%> deg C</h2>
</body>
Attribute |
Values |
Description |
---|---|---|
AspCompat |
true | false |
Causes this page to run on an STA thread for backward compatibility |
AutoEventWireup |
true | false |
Determines whether events will be auto-wired up (see Chapter 2) |
Buffer |
true | false |
Enables HTTP response buffering |
ClassName |
Any name |
Specifies the name of the class to be generated by this file |
ClientTarget |
User agent or alias |
Specifies the target user agent to use when accessing this page |
CodePage |
Code page value |
Code page value for the response |
CompilerOptions |
String of compiler options |
Compiler options to be added to the compilation command when the page is compiled |
ContentType |
Any HTTP type string |
MIME type of response for this page |
Culture |
Culture name |
Culture to be used when rendering this page |
Debug |
true | false |
Whether this page is compiled with debug symbols |
Description |
Any text |
Not used |
EnableSessionState |
true | false |
Whether session state is used on this page (see Chapter 10) |
EnableViewState |
true | false |
Whether view state is enabled for this page (see Chapter 2) |
EnableViewStateMac |
true | false |
Whether ASP.NET computes a Message Authentication Code (MAC) on the page's view state (to prevent tampering) |
ErrorPage |
Valid URL |
Target URL redirection for unhandled exceptions (see Chapter 5) |
Explicit |
true | false |
For VB.NET, whether explicit declaration of variables is mandated |
Inherits |
Class name |
Code-behind class from which this page will inherit |
Language |
Any .NET language |
Default source language of this page |
LCID |
Locale ID |
Locale ID to use for this page |
ResponseEncoding |
ASCIIEncoding UnicodeEncoding UTF7Encoding UTF8Encoding |
Response encoding for the content of this page |
Src |
Source file name |
Source file name of the code-behind class to be dynamically compiled when the page is compiled |
SmartNavigation |
true | false |
Enables smart navigation feature for IE 5 and higher (saves scroll position without flicker) |
Strict |
true | false |
For VB.NET, whether option strict mode is enabled |
Trace |
true | false |
Whether tracing is enabled for this page |
TraceMode |
SortByTime SortByCategory |
When tracing is enabled, how the messages are displayed |
Transaction |
Disabled NotSupported Supported Required RequiresNew |
Whether and how this page participates in a transaction |
UICulture |
Any valid UI culture |
UI culture setting for this page |
WarningLevel |
0–4 |
Warning level at which compilation for this page is aborted |
Listing 1-16 Specifying Additional Compiler Options for a Page
<%@ Page Language='C#'
CompilerOptions="/warnaserror+ /checked+" %>
</html>
7,新的内部对象
Listing 1-17 HttpRequest Class
public sealed class HttpRequest
{
public string[] AcceptTypes {get;}
public string ApplicationPath {get;}
public HttpBrowserCapabilities Browser {get; set;}
public HttpClientCertificate ClientCertificate {get;}
public Encoding ContentEncoding {get;}
public int ContentLength {get;}
public string ContentType {get;}
public HttpCookieCollection Cookies {get;}
public string CurrentExecutionFilePath {get;}
public string FilePath {get;}
public HttpFileCollection Files {get;}
public Stream Filter {get; set;}
public NameValueCollection Form {get;}
public NameValueCollection Headers {get;}
public string HttpMethod {get;}
public Stream InputStream {get;}
public bool IsAuthenticated {get;}
public bool IsSecureConnection {get;}
public NameValueCollection Params {get;}
public string Path {get;}
public string PathInfo {get;}
public string PhysicalApplicationPath {get;}
public string PhysicalPath {get;}
public NameValueCollection QueryString {get;}
public string RawUrl {get;}
public string RequestType {get; set;}
public NameValueCollection ServerVariables {get;}
public int TotalBytes {get;}
public Uri Url {get;}
public Uri UrlReferrer {get;}
public string UserAgent {get;}
public string UserHostAddress {get;}
public string UserHostName {get;}
public string[] UserLanguages {get;}
// Methods
public byte[] BinaryRead(int count);
public int[] MapImageCoordinates(string name);
public string MapPath(string path);
public void SaveAs(string filename, bool includeHdrs);
}
Listing 1-18 HttpResponse Class
public sealed class HttpResponse
{
public bool Buffer {get; set;}
public bool BufferOutput {get; set;}
public HttpCachePolicy Cache {get;}
public string CacheControl {get; set;}
public string Charset {get; set;}
public Encoding ContentEncoding {get; set;}
public string ContentType {get; set;}
public HttpCookieCollection Cookies {get;}
public int Expires {get; set;}
public DateTime ExpiresAbsolute {get; set;}
public Stream Filter {get; set;}
public bool IsClientConnected {get;}
public TextWriter Output {get;}
public Stream OutputStream {get;}
public string Status {get; set;}
public int StatusCode {get; set;}
public string StatusDescription {get; set;}
public bool SupressContent {get; set;}
// Methods
public void AddHeader(string name, string value);
public void AppendCookie(HttpCookie cookie);
public void AppendHeader(string name, string value);
public void AppendToLog(string value);
public void BinaryWrite(byte[] data);
public void Clear();
public void ClearContent();
public void ClearHeaders();
public void Close();
public void End();
public void Flush();
public void Pics(string value);
public void Redirect(string url);
public void SetCookie(HttpCookie cookie);
public void Write(string value);
public void WriteFile(string fileName);
}
Listing 1-19 HttpServerUtility Class
public sealed class HttpServerUtility
{
public string MachineName {get;}
public int ScriptTimeout {get; set;}
// Methods
public void ClearError();
public object CreateObject(string obj);
public object CreateObject(Type objType);
public object CreateObjectFromClsid(string clsid);
public void Execute(string url);
public void Execute(string url, TextWriter output);
public Exception GetLastError();
public string HtmlDecode(string value);
public string HtmlEncode(string value);
public string MapPath(string path);
public void Transfer(string url);
public string UrlDecode(string url);
public string UrlEncode(string url);
public string UrlPathEncode(string url);
}
8,小结
Asp.net从ASP3.0发展而来,却发生了根本性变化。它不再使用解释,而是把页面编译成一个System.Web.UI.Page派生的类。 asp.net的整个运行架构就是一个类的集合,基于类进行对象建模。并采用Code-Behind,Shadow Copy等技术实现页码与代码分离,Xcopy部署等功能。