首页 > 代码库 > ASP.NET - 处理页面

ASP.NET - 处理页面

客户端与服务端数据交互

要把本地数据提交给服务端,就要使用form元素,服务端通过request[表单元素的name]就可以获取表单元素的value。

form的两种提交方式

Get方式:提交的表单数据会显示在浏览器地址栏的地址后边,数据量小使用Get方式。此为默认。

Post方式:以密送的形式提交表单的数据到服务器,数据量比较大的时候使用Post方式。只要在页面点击过表单里点击过提交按钮,那么当你点击浏览器的刷新按钮或右击页面刷新都会产生提交行为,也即会产生重复提交表单数据。

技术分享
<form action="Handler.ashx" method="post"></form>
View Code

无论get或post,request只能获取属于表单的元素的value,不包括其他html元素的值,比如一个div即使放在form里也不属于表单元素。

服务器控件的form

如果使用了服务器控件,那么包含它们的form也必须设定为runat="server",否则服务器控件可能会出现非预期的行为。 

技术分享
<form id="form1"><!-- form必须加上runat="server"-->    <asp:Label ID="labelText" runat="server" Text="hello" EnableViewState="true"></asp:Label>    <input type="submit" value="ok" /></form>
View Code

 

一般处理程序

你可以创建一个后缀名位ashx的文件,这是一个简易的处理程序文件,一般用于处理html页面。它不像aspx文件那样结构复杂并且和aspx一样可以处理客户端请求。这种文件是一个http模块,不像aspx模块那么臃肿,需要实例化服务器控件后转化为html视图才呈现最终的页面。

新建一个html页面 代码如下:

技术分享
<form action="Handler.ashx"><input type="text" name="text" /><input type="submit" value="提交"/></form>
View Code

新建一个Handler.ashx文件

技术分享

技术分享
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace hr{    public class Handler : IHttpHandler    {        public void ProcessRequest(HttpContext context)        {            context.Response.ContentType = "text/html";            string InputValue = http://www.mamicode.com/context.Request["name"];            context.Response.Write(InputValue);        }        public bool IsReusable        {            get            {                return false;            }        }    }}
View Code

该程序接收到一个请求(request) 然后获取输入框的值并将值返回给客户端。

技术分享
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace hr{    public class Handler : IHttpHandler    {        public void ProcessRequest(HttpContext context)        {            context.Response.ContentType = "text/html";            string InputValue = http://www.mamicode.com/context.Request["name"];            if (string.IsNullOrEmpty(InputValue))            {                //第一次访问ashx页面            }            else            {                            }        }        public bool IsReusable        {            get            {                return false;            }        }    }}
View Code
技术分享
context.Response.ContentType = "text/html"; //表示这个文件返回的是html数据context.Response.ContentType = "image/jpeg"; //表示这个文件返回的是图片数据//向客户端写入文本数据仅需使用Response.Write( ) //写入其它类型的数据需要使用Response.WriteFile( );
View Code

ashx不会返回原来的html页,所以一般用于处理请求,然后redirect到其他页面。如果确实需要保持原来的html页,可以使用文件类来读取原来的html页。

技术分享
string fullPath = context.Server.MapPath("HTMLPage.htm"); string content = System.IO.File.ReadAllText(fullPath); context.Response.Write(content);//或直接Redirect也可以
View Code

如果需要将新数据返回客户端,可以在html里这样设置:

技术分享
<input type="text" name="text"  value="@value" />
View Code
技术分享
//保持原html页的用户录入的表单数据的呈现string fullPath = context.Server.MapPath("HTMLPage.htm");string content = System.IO.File.ReadAllText(fullPath);string inputText = context.Request["text"];content = content.Replace("@value", inputText);context.Response.Write(content);
View Code

常规处理程序

aspx文件分aspx和cs文件,cs是作为响应客户端请求的程序处理文件,该文件表示为一个类。当客户端请求时,cs会实例化为一个页面处理对象,aspx会实例化为一个页面呈现对

象,aspx派生自cs。(如果在cs里定义一个私有的属性或方法 那么它们不能被外部访问)。

aspx.cs程序不处理html元素,它只能处理服务器控件。如:

技术分享
<form id="form1" runat="server"><asp:Label ID="Label1" runat="server" Text="Label">100</asp:Label><asp:Button ID="Button1"  runat="server" Text="Button" onclick="Button1_Click1" />        </form>
View Code
技术分享
//点击按钮提交到服务端,在按钮事件中你可以获取到Label1的值protected void Button1_Click1(object sender, EventArgs e){      Response.Write(Label1.Text);}
View Code

使用IsPostBack属性

该属性返回一个bool值,表示该页面是否是用户通过点击了该页面的表单提交按钮提交到服务器后并返回的,如果是则返回true。

技术分享
if (!IsPostBack){//页面不是提交并回发的,做出处理……}
View Code

无状态的http

客户端的每一次请求都会促使服务端重新实例化Page页面对象,这样我们就无法利用该对象存储一些属性记录一些数据。因为这个对象转化为html呈现给用户后就已经被销毁。此为无状态的http,为了解决这个问题,可以参考下面几种方式。

I.在服务器端保存数据

将数据保存在服务器端而不是客户请求的页面里。

Session:Session池保存的数据为每个客户所独有。

Application:Application池保存的数据为客户所共享。

Caching:缓冲池。

Database:数据库。

II.在客户端保存数据

Hidden Filed:隐藏域。

ViewState:视图状态。

Cookies:物理数据。

Control State:几乎不用。

Query String:查询字符串。

III.ViewState视图状态

ViewSate原理就是服务端使用BinaryFormatter实例的Serialize方法(参看文件和流文档)将ViewSate数据序列化然后存入一个隐藏域(input Hidden )发送到客户端去 类似下面这样:

技术分享
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTI2NTY4ODI3MQ9kFgICAw9kFgICAQ8PFgIeBFRleHQFATBkZGT4BdDD24k/Xrj+/02LIA3JLjpsL2sMllaEeR67KBrPRw==" />
View Code

当你在服务端创建了一个ViewSate对象并设置了其值后,服务端会将ViewSate数据序列化然后存入一个hidden input并发送到客户端去,这个隐藏域存储了一些数据,当客户端再次发出请

求时,这个隐藏域也会随着表单被提交到服务器端,然后隐藏域的数据会被反序列化为ViewSate对象,这样你又可以继续读取这个数据了,数据得到了保存,不再是无状态。

技术分享
<form id="form1">    <input type="submit" value="ok" /></form>
View Code
技术分享
protected void Page_Load(object sender, EventArgs e){    ViewState["name"] = "sam";    if (IsPostBack)    {        Response.Write(ViewState["name"]);    }    else    {        Response.Write("首次请求");    }}
View Code

ViewSate可存储的数据类型有:string、int、bool、List<T>、ArrayList、Array、HashTable和一些自定义的数据类型,格式很简单:

技术分享
ViewSate["key"]=value;
View Code

ViewState与服务器控件

我们知道html中只有表单元素才可以提交数据给服务端,而所有的服务器控件都能提交数据,也就是说使用服务器控件可以保存数据以便服务端可以取出数据。这是因为所有服务器控

件都有一个EnableViewState属性,只要设定为true,服务端就会为其创建隐藏域存储它的值。

技术分享
<form runat="server" id="form1">    <asp:Label ID="labelText" runat="server" Text="hello" EnableViewState="true"></asp:Label>    <input type="submit" value="ok" /></form>
View Code
技术分享
protected void Page_Load(object sender, EventArgs e){                if (IsPostBack)    {        Response.Write(labelText.Text);    }    else    {        Response.Write("首次请求");    }}
View Code

ViewState缺点

如果一个页面的ViewState太多,将会造成额外的负担,造成访问速度的降低。如果把大型数据存入诸如Label这样的控件中,那么最好将其ViewState设为false,否则将会生成一个超大的隐藏拖慢页面访问速度而且机密数据放入ViewState更会有安全隐患。(* 使用客户端的JS程序动态插入数据到控件上 那么该数据不会存储到对应的隐藏域中)。

禁用ViewState

将控件的属性EnableViewState设为False会禁用该控件的ViewState。

技术分享
<asp:Label ID="labelText" runat="server" Text="hello" EnableViewState="false"></asp:Label>
View Code

将页面的Page指令的ViewState设为False会禁用整个页面的ViewState。

技术分享
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" EnableViewState="False" %>
View Code

 

特殊目录

在ASP.NET程序中使用内置的DataDirectory类即可表示数据库文件所在的文件夹,即App_data文件夹。它返回一个数据库文件的绝对路径,在获取数据库连接字符串时可以考虑使用DataDirectory。

App_Code文件夹

包含要在应用程序中使用的动态编译的源代码文件,这些文件通常是独立的组件,比如自定义的类文件。当在此目录创建类文件后,web项目里的所有cs文件都可以访问这个类且不必引入命名空间。编译器会自动编译里边的内容并自动让每个文件都可以引用这个类。只有web网站项目才有这个文件夹,如果是asp.net应用程序,即使你创建了这个文件夹,也不起作用.你可以创建asp.net文件夹的App_LocalResources文件夹,注意需要右击类文件-属性-高级-生成操作-编译且需要引入命名空间。

Bin文件夹

包含被编译过的程序集(.dll), 此目录专门用于大型项目,创建的组件类可以放在这个目录下由程序编译为dll文件。使用类库时需要在外部添加命名空间来引用bin目录下的类库中的类。

App_GlobalResources文件夹

此目录包含的资源是整个web的全局资源,可以被程序的所有页面访问。

App_LocalResource文件夹

类似App_GlobalResources,不过它还可以包含只被特定的页面访问的资源。

App_WebReferences文件夹

保存Web应用程序对所使用的Web服务的引用 包括WSDL文件和发现文档。

App_Data文件夹

包含数据库文件和xml文件。

App_Themes文件夹

包含Web应用程序所使用的主题文件。

 

全局应用程序文件

这是一个Global.asax文件,它派生自HttpApplication类,在这个文件中你可以编写响应整个Web应用程序的事件,当事件被派发后你可以决定如何做出响应。编写右击项目-新建-全局应用程序类即可创建

Global.asax文件,默认当你创建asp.net应用程序时会自动为你创建该文件。(Global.asax文件只能创建一个且必须位于站点根目录下)。

全局应用程序事件 

Application_BeginRequest

每次请求开始就触发。 

Application_AuthenticateRequest

在执行验证前被触发 这是穿件你自己的验证逻辑的起点。 

Application_AuthorizeRequest

用户验证完毕后触发 此时可以在此事件中为识别了的用户提供一个权限。 

Application_ResolveRequestCache

在ASP.NET 页面框架完成一个授权请求时,该事件被触发。它允许缓存模块从缓存中为请求提供服务,从而绕过事件处理程序的执行。 

Application_AcquireRequestState

在位客户读取会话特定的信息并把信息填充到session集合前被触发。 

Application_PreRequestHandlerExecute

在ASP.NET 页面框架开始执行诸如页面或Web 服务之类的事件处理程序之前,该事件被触发。 

Application_PreSendRequestHeaders

在ASP.NET 页面框架发送HTTP 头给请求客户(浏览器)时,该事件被触发。 

Application_PreSendRequestContent

在ASP.NET 页面框架发送内容给请求客户(浏览器)时,该事件被触发。 

Application_PostRequestHandlerExecute

在ASP.NET 页面框架结束执行一个事件处理程序时,该事件被触发。 

Application_ReleaseRequestState

在ASP.NET 页面框架执行完所有的事件处理程序时 该事件被触发 这将导致所有的状态模块保存它们当前的状态数据。 

Application_UpdateRequestCache

ASP.NET页面框架完成事件处理程序的执行后 该事件被触发 从而使缓存模块存储响应数据 以供响应后续的请求时使用。 

Application_EndRequest

请求结束时但在对象被释放和重新创建前被触发 适合在这里清理代码。

Application_Start

在应用程序启动时触发。 

Application_End

在应用程序关闭时触发。 

Application_Error

在出现未处理的错误时触发。 

Session_Start

在新会话启动时触发。 

Session_End

会话结束时触发。需要在Web.config文件中的system.web配置节里指定sessionstate节点并将其模式设置为InProc 时,才会引发此事件。设置为 StateServer或 SQLServer,则不会引发该事件。

全局配置文件

配置文件的数据用于整个web,你可以在任何位置读取这些数据。每个asp.net应用程序都继承了machine.config和web.config文件所表示的类,通过这两个类你可以在程序代码任意处访

问它们的属性,这些属性都是以配置节的形式定义在machine.config和web.config文件里。

基本结构

<configuration>

<configSections>:注册可选的System.web.extensions节点 asp.net能够识别它并指导如何处理其中的数据。

<appSettings>:存储你自定义的设置。

<connectionStrings>:配置数据库连接字符串。

<system.web>:配置config文件里各个方面的节点 。

<system.codedom>:配置页面使用最新版本的C#编译器。

<system.webServer>:配置Asp.Net Ajax在IIS下工作。

<system.web.extensions>:配置Asp.Net Ajax特性。

</configuration>

system.web配置

customErrors

配置各种http错误,你可以配置http错误所对应的重定向页面。

属性

mode

启用或关闭自定义http错误,可能的值:On、Off。

ReMoteOnly

自定义错误只显示给客户端看,服务器端看到的是完整错误信息页面。

defaultRedirect

http错误后导向的页面。

技术分享
<customErrors mode="On" defaultRedirect="OtherError.html">    <error statusCode="404" redirect="404Error.html" /></customErrors>
View Code

connectionStrings配置

除了可以在此处配置数据库连接字符,还可以在appSetings节点里配置。

技术分享
<connectionStrings>    <add name="DatabaseConnectionStr" connectionString="uid=sa;pwd=123;server=幻听_PC;database=mydb" /></connectionStrings>
View Code
技术分享
<connectionStrings>    <add name="HR_Connection" connectionString="server=DESKTOP-O1G47PT;uid=sa;pwd=123456;database=HR_DB;" providerName="system.Data.SqlClient"/>  </connectionStrings>
View Code

读取

获取数据库连接字符需要引用System.Configuration.dll,使用ConfigurationManager类来读取。

技术分享
SqlConnection conn = new SqlConnection();conn.ConnectionString = ConfigurationManager.ConnectionStrings["HR_Connection"].ConnectionString;return conn;
View Code

 appSettings配置

完全的自定义,用以配置以键值对(Key与Value)方式出现的变量。

技术分享
<appSettings>    <add key="PubSqlConnectionStr" value=http://www.mamicode.com/"server=简单粗暴-PC;uid=sa;pwd=123;database=HeTonPlastics;" />        </appSettings>
View Code

读取

获取键值需要引用System.Configuration.dll,使用ConfigurationSettings类来读取。

技术分享
string str = System.Configuration.ConfigurationSettings.AppSettings["PubSqlConnectionStr"];
View Code

附:WebConfigurationManager类 

此类提供对asp.net web配置文件(web.config或machine.config文件)的访问和读取。需要引用System.Web.Configuration.dll。

方法 

OpenWebConfiguration(x) 

x是web.config配置文件路径,根据参数指定的配置文件所在路径打开这个文件,返回一个Configuration对象。 

技术分享
Configuration config= System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/Web.config");
View Code

OpenMachineConfiguration(x) 

x是machine.config配置文件路径,根据参数指定的配置文件所在路径打开这个文件,返回一个machineConnfig对象。 

附:Configuration类 

表示一个配置文件

方法 

GetSection(x) 

x是要获取的节点的名字,获取指定的节点对象。 

Save 

动态修改配置节后需要使用此方法来立即更新配置文件。

通过WebConfigurationManager和Configuration这两个类,你就可以很轻易的读取任何配置节存储的数据。即得到了Configuration就可以得到config文件中的任何节点对象,通过节点对象得到它们存储的数据。 

技术分享
<configuration>      <appSettings>            <add key="name" value=http://www.mamicode.com/"sam"/>      </appSettings><configuration>
View Code
技术分享
protected void Page_Load(object sender, EventArgs e){    //打开配置文件    Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/Web.config");    //获取配置文件里某个节点 返回的是以节点名称开头后缀都是Section结尾的配置节点对象 比如获取appSettings配置节,得到的就是AppSettingsSection,以此类推。    AppSettingsSection set = (config.GetSection("appSettings")) as AppSettingsSection;    //获取键值    Response.Write(set.Settings["name"].Value);}
View Code

附:ConfigurationSettings类

ConfigurationSettings类提供访问appSettings配置节存储的数据。不过此方法已经过时。

Page页的呈现

每个web窗体都派生自System.Web.UI.Page,客户端一旦发生请求到服务端,最先进入的程序就是Page_Load事件而不是其它你定义的方法,比如当用户修改了表单数据点击提交按钮之后,假设你在提交按钮上注册了事件,那么首先这个请求会进入Page_Load执行该事件处理程序,它会先呈现客户端页面,接下来才会进入button_Click事件处理程序。这也就解释了为什么表单提交后页面刷新完成而表单显示的数据是修改之前的数据,因为它先呈现页面,然后才去更新数据。如果要立即显示修改后的数据,要么使用Response重定向要么加上下面这段代码。 

if (!IsPostBack){   GetConfig();//获取数据库数据}

这样,当通过提交按钮提交新数据后,进入Page_Load事件处理程序,程序就会忽略上面的代码而将服务器控件(表单文本框)所对应的viewstate(隐藏域)的数据读出来再次填充到表单里,因为表单的数据被用户修改,所以隐藏域的值也相应的自动被更改,这样提交数据后,隐藏域的值被程序自动取出来又回发给了客户端,所以我们可以看到点击提交按钮后,表单显示的就不再是原来的数据了,实际上它是从隐藏域读取数据去填充表单而非从数据库里读取数据进行填充,直到你关闭页面再次发出请求,GetConfig才会执行。

 

 ASP.NET - 学习总目录

ASP.NET - 处理页面