一个服务器有一个machine.config文件,这个文件是该服务器上所有的web应用程序所公用的。
每一个应用程序都可以有一个名为web.config的配置文件,该配置文件放在web应用程序的根目录下。
Asp.net不依赖元库来保存应用程序的配置信息,而是依赖一个xml格式的配置文件。
对配置文件的改变,会马上应用于该web应用程序在配置文件修改之后的所有连接。Asp.net通过监听操作系统所提供的文件改变通知,探测到machine.config或web.config这样的文件发生了改变。
Asp.net消除了元库99%的操作,但是有两点例外:创建web应用程序;定制文件扩展名映射。
配置文件是区分大小写的,一般来说,首字母是小写的,以后每个单词的首字符要大写。
在<configuration>下一般包含两类重要的组成部分:配置项处理程序;配置项设置。
可以强制执行machine.config中的设置,这样web.config文件就不能覆盖这些设置了。
理解 配置项处理程序 的配置和配置项配置 是很重要的。通过该书的讲解,我已对配置文件的基本结构有了了解。所谓的配置项处理程序就是制定一个用来处理这个配置项的类。而配置项则用来制定该配置项所对应类的一些参数。
另外,SessionGroup是一个很好的实现hierachy的方法。在其他方面SessionGroup并没有什么用处。
比如:
配置项处理程序的配置如下:
<configuration>
<configSections>
…
<sectionGroup name="system.web" type="System.Web.Configuration.SystemWebSectionGroup, System.Web, Version=
…
<section name="sessionState" type="System.Web.Configuration.SessionStateSection, System.Web, Version=
…
</sectionGroup〉
…
</configSections>
</configuration>
配置项的配置如下:
<configuration>
<system.Web>
<sessionState
mode=”incProc”
stateConnectionString=”tcpip=127.0.0.1:
stateNetworkTimeout=”
sqlConnectionString=”data source 127.0.0.1; user id = sa; password=”
cookieless=”true”
timeout=”
/>
</system.Web>
</configuration>
这里配置项配置的就是上面System.Web.Configuration.SessionStateSection类的一些属性的值,在创建该类的对象时,会自动从这个配置文件中读取这些属性的值来初始化
在应用程序中如果要用到某一个配置文件的值,那么就可以调用在配置项处理程序中配置的类来取得这些值。
该设置是文件夹级别的。
这其中有一个Application shut down time ,这个属性是用来设置应用程序的关闭时间。假如我把这个值设置为10,就是说如果在10分钟之内没有人访问这个web应用程序,那么在服务器端我将把这个应用程序所占用的内存释放,退出该程序。下次要使有人来访问该程序,服务器再重新把它加载到内存中。
在asp.net中,当iis接受到一个请求的时候,他把请求传送给一个叫做aspnet_ isapi.dll的dll,接下来,如果是iis5,责该dll会把请求传送给一个叫做aspnet_wp.exe的程序来处理。如果是iis6或者更高版本,则传递给一个叫做w3wp.exe的程序来处理。
那么这里的aspnet_isapi.dll就可以通过一个叫做processModel的session来配置。
这里要注意一个问题,由于aspnet_isapi.dll是一个unmanaged的dll,所以对这个配置所作的修改需要reset iis才能够生效。
在1.1的时候并不提供通过程序编辑配置文件的功能。
但是在2.0中已经具备了,并且功能十分强大,所有编辑配置文件相关的类都放在了:System.Configuration和System.Web.Configuration两个命名空间当中。这些类不但支持本地编辑,而且能够编辑网络远端的文件,所以对于网站维护人员远程维护web应用程序是十分方便的。
所谓的状态管理指的是,一个页面的数据要能够传送到另外一个
通过本章的章节安排,我们就能看到,session依旧是他的重点。
提到状态的管理,方法就有很多了,有服务器端的,有客户端的;
Session就是典型的服务器端的方法;而cookie则是典型的客户端方法;但是说实话,我对这些状态管理的方法一个也不了解。需要以后逐个来了解,现在就以session来作为突破口吧。
由于我本来对session不够了解,所以在阅读不章之前,我先阅读了我的blog上的一篇文章,地址为:http://www.cnblogs.com/strinkbug/articles/538063.html。通过本文的会员卡例子,我们就能够对http中的状态及其状态保持机制有个比较完整的了解。
这里要注意的一点是:该讲座所讲的内容是基于vs2003的,所以在看完之后还是需要再看看《professional asp.net 2.0》以便了解2.0和1.1有什么不同。
状态管理主要分为:基于服务器端的状态管理和基于客户端的状态管理。
http连接的过程:
l 连接到服务器;
l 告诉服务器想要的页面地址;
l 服务器发送给对应的页面内容;
l 断开连接,服务器把客户端忘得干干净净;
(1) 基于客户端的状态管理;
a) 视图状态(ViewState)
这个是asp.net中特有的。
所有的服务器端控件都这么一个属性,虽然是这么说,其实只有一个ViewState对象,这个对象在page中,所有支持ViewState的服务器控件的ViewState都保存在这个对象当中。
由于不存在加密性,而且内容都是放在客户端,所以不能在这里保存诸如用户名密码文件路径等相关信息。
可以往viewState里头放诸如:整数,布尔型,字符串,字符等一些基本类型类型,以及这些类型的hash表。
Asp.net默认会在page中创建一个__VIEWSTATE的input隐藏控件。Viewstate就保存在这个控件当中。
所以其实我觉得所谓的视图状态,其实到底还是通过隐藏窗体域的方式来实现的。
b) 隐藏窗体域;
其实就是一个隐藏得控件。
现在一般已经不使用;
c) Cookie;
用途:
Remember me ;
个性化设置;
弹出窗口;
使用:
Response.Cookies[“…”].Value= ….
Request.Cookie[“…”].Value
通过其中的…指定想要量的名字即可。
这里有点要说明:就是如果要往cookie中添加一个量,并不要申明,直接赋值就可以了,比如现在要往cookie中存放一个叫做user的量,做法如下:
Response.Cookie[“user”].Value=”strinkbug”;
d) 查询字符串;
查询字符串就是通过在地址之后加上一个带有问号的赋值字符串来传递参数。
在使用的时候则通过:Request.Params[“…”].Value 来获取。
这里要注意的一个问是:大多数的浏览器都把url的长度限制在255的范围之内,所以如果查询字符串的长度过长的话,则可能发生错误,或者无法传递。
涉及到安全问题的字符串一定不能用查询字符串来传送。
(2) 基于服务器端的状态管理;
基于服务器的状态管理主要有两种方式:
a) Application
只有当应用程序重起之后才可以清除Application中保存的状态。
这里还牵涉到:
Application.Lock()
Application.Unlock()
两个方法的使用。
对Application中的参数进行操作的时候,一般都要调用Application.Lock()方法和unlock()方法,因为很可能同一时间有很多个用户都在访问服务器,如果不锁上的话,就可能造成资源访问冲突。
对于频繁使用的信息建议使用该对象,但是不要用它来存放太大的信息。
Application 和session是有区别的,application中存放的是所有用户共享的信息。
而Session中存放的是某个用户在某一段时间内的信息。
对于频繁使用的数据使用该对象。
如果数据量很大的话,可以使用web.config;
b) Session;
Session的使用:
假设现在有两个页面:
UseSession_Source.aspx --1
UseSession_Destination.aspx --2
在1中的代码如下:
protected void Button1_Click(object sender, EventArgs e)
{
Session["user"] = TextBox1.Text;
Session["password"] = TextBox2.Text;
Response.Redirect("UseSession_Destination.aspx");
}
在2中的代码如下:
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = Session["user"] + "您好!";
Label2.Text = "您的密码是:"+Session["password"];
}
Session 和Application的区别可以做如下一个比喻:手机开机就是一个Application启动了,开始打一个电话,就是一个session启动了。在用手机打电话时,你一般会问:你是谁?那么这个谁就是保存在session中的信息。而手机中的电话本就是保存在Application中的信息。
c) 数据库
当数据量比较大,或者在应用程序重起之后还要能够保存原来的数据时,一般就会使用数据库;
在asp.net 2.0中,提供了另外几种新的状态管理方式:一个是为session提供了数据库的存储方式,还有custom的存储方式(因为session的数据库存储方式只能存储在sql server中,所以提供了custom的方式,可以让用户扩展到其他的数据库当中去);Control State方式;cross-page postback方式。
这几个方式到目前为止还没有看。
Session在asp.net 2.0中有以下三种存储方式:in process, out of process, database。
一般来说,在一个Application中,所有的页面都有着相似的外观,比如相同的色调,相同的字体,相同的控件风格等等。
一般来说,讲到theme就会想到skin和css,那么skin和css有什么区别呢?
其实一般来说,皮肤和css是差不多的,但是皮肤只能在asp.net中使用,而css可以在所有类型的页面中使用。Skin只能用于Server control,而css可以用于所有类型的控件。
考虑到使用server control的效率较低,所以我开始怀疑使用skin的场合是不是会那么多?
在一个page中用Theme关键字来添加一个主题,但是要注意,如果用Theme来添加主题,那么该页的所有控件的属性设置都会失效,因为Theme的优先级高于本地的优先级。
所以如果你想要单独设置某个控件的属性,采用如下的方式是不行的:
<asp:Textbox ID=”TextBox
BackColor=”#
而应该采用如下的方式:
<asp:Textbox ID=”TextBox
BackColor=”#
如果你是采用web.config来定义主题的,而此时你想让某个页面不要应用该主题,那么你就可以使用如下的方式:
<%@ Page Language=”C#” EnableTheming=”False” %>
有个比较好玩的特性是:即时你对某个页面使用了上述的方式,可是你还想让这个页面的某个控件使用主题,此时你可以使用如下的方式:
<asp:Textbox ID=”TextBox
BackColor=”#
另外,在这里要顺便说明一下如何在web.config中定义定义整个application的主题。
<?xml version=”
<configuration>
<system.web>
<pages theme=”SmokeAndGlass” />
</system.web>
</configuration>
<%@ Page Language=”c#” StylesheetTheme=”Summer” %>
一般来说,主题都会放在一个叫做App_theme的文件夹当中。
一般来说,对于一个application不会只有一个主题,所以在app_Theme中肯定会有多个子文件夹。每个子文件夹代表一个主题,不如春夏秋冬,比如日夜,比如男女,比如用户自定义,等等。
在一个主题文件夹当中,一般会有以下类型的文件:
l 一个(只能有一个)*.skin的文件;
l Css样式表;
l 一些图片;
考虑到skin只能应用于server control,所以css的使用还是十分必要的。
当skin和css冲突的时候,skin优先;
其实之所以说skin比css更适合于保持一个统一的风格,一个很重要的原因就是可以使用图像。
比如你想要让一个TreeView显示出图片,就可以使用下面的例子;
<asp:TreeView
runat="server"
BorderColor="#FFFFFF"
BackColor="#FFFFFF"
ForeColor="#585880"
Font-Size=".9em"
Font-Names="Verdana"
LeafNodeStyle-ImageUrl="images\summer_leaf.bmp"
/>
能够显示的图片格式很多,可以是jpg,bmp,gif等格式。
有的时候,你可能在skin中无法使用某些图片,于是你就可以通过css来定义一些样式,这些样式就是通过使用图片来定义的,然后在skin中使用这些样式。通过这种方式,你就可以使用任何你想要实现的样式。
在你的应用程序中,对于同一种控件,你可能希望在不同的场合显示为不同的样式,此时你就需要为这一种控件定义多个主题。
在这种时候,SkinID就派上用场了。
?Skin是用来区分同一个类型多个主题,那么我要问的是:不同类型控件的SkinID是否可以相同呢?
protected void Page_PreInit(object sender, System.EventArgs e)
{
Page.Theme = Request.QueryString[“ThemeChange”];
}
在这里要注意的一点就是:如果要在程序中指定主题,那么必须在Page的Page_PreInit事件处理函数中或者在这个事件发生之前。
如果是动态控件,那么在必须再将这个控件添加到容器之前指定。
不只是皮肤可以在程序中指定,甚至是控件的SkinID也可以在程序中指定。例子如下:
protected void Page_PreInit(object sender, System.EventArgs e)
{
TextBox1.SkinID = “TextboxDashed”;
}