ASP。NET Web表单模型,部分呈现和事件
介绍 通过参考ASP获得Web应用程序环境及其约束的概述。NET AJAX,请阅读我之前的文章:关于ASP的Web应用程序的说明。净AJAX。 正如在那篇文章中所讨论的,我们知道web应用程序在本质上是无状态的,并且它在断开连接的模式下工作,即。, Web服务器总是将传入的客户机请求作为新请求处理,而与先前的请求没有任何连续性。当我们试图理解基于事件的ASP的底层概念时,请记住这一点。NET Web表单编程模型。 基于事件的编程模型从著名的Hollywood原则中被概念化:“不要打电话给我们,我们会打电话给你”(Hollywood原则)。它是一个非常有用的范例,可以帮助我们开发易于理解(具有高内聚)和易于维护(低耦合)的代码。这是如何实现的?使之成为可能的关键是牺牲控制元素,就像在传统的程序流程中那样。所以在我们的例子中,不是让应用程序驱动系统(其中包括ASP。NET运行时),asp.net运行时。NET运行时驱动应用程序。 要使这种编排(使用基于事件的编程模型)成功,并与ASP无缝集成。因此,作为开发人员,我们应该按照框架(在本例中是ASP.NET)的一些约定和要求编写代码,这就是我们将在本文中讨论的内容。 我不会涉及严格的细节,比如文档对象模型(DOM)和DOM中的事件传播(事件冒泡)等等。但是我将试着说明ASP。NET设计者想要达到的目标,以及我们如何通过使用这个模型获得好处。本文将介绍服务器端和客户端事件模型,然后使用ASP。NET服务器控件,我们将演练从客户端到服务器并返回(在post-back中往返)。 我用过小提琴工具拦截过电线的信号。我们将分析这些数据,以获得在页面的每次往返中在客户机和服务器之间流动的有效负载的内部视图。请注意,我们不会进入ASP。NET内部工作,描述一个项目的每个发布文件,而不是在概念层次上讨论一切。 概述 在ASP。NET Web表单模型中,一个页面由两部分组成:视觉元素(HTML、服务器控件、静态文本、CSS、JavaScript等)和页面的编程逻辑。Microsoft的IDE (Visual Studio)将这两个不同的部分存储在两个单独的文件中。可视元素在.aspx中创建,代码在单独的类文件中,称为代码隐藏类文件(.aspx.vb或.aspx.cs)。当然,正如您将看到和我们将讨论的那样,更好的做法是将用于页面行为的CSS样式和JavaScript代码保存在浏览器内,而不是.aspx之外,以获得更好的可读性和重用性。你可以在随函的样品中找到这种方法。 正如上面所讨论的,尽管Web表单页面由两个独立的文件组成,但当应用程序运行时,它们一起构成一个单元。项目中所有Web表单的代码隐藏类文件被编译为项目生成的动态链接库(.dll)文件。Web表单的.aspx页面文件也被编译,但编译的方式不同。每当一个Web表单页面被请求时,.dll文件就在服务器上运行。在运行时,这个.dll文件处理传入的请求,并通过创建动态输出并将其发送回浏览器或客户端设备进行响应。 如果页包含服务器控件(如示例中所示),则派生的页类充当控件的容器。这些控件的实例是在服务器上运行时创建的,然后Page类为浏览器或客户端设备呈现输出。 这个Page类实际上建模了整个Web表单页面。页面经历一系列处理阶段(称为页面生命周期)。这包括初始化、实例化控件、恢复和维护状态、执行事件处理程序代码,最后是呈现。页面中包含的服务器控件(在开发自定义服务器控件时需要知道这一点)也遵循类似的页面生命周期。 Page类有一个独特的“render”阶段——出现在页面生命周期接近结束时,即生成输出的时候。注意,“渲染”是一个处理阶段,而不是一个事件。在呈现之前,视图状态(页面视图状态由ASP管理。一个隐含输入形式的网络。控件,并用于在页面到服务器的往返中持久化状态/信息)为页面和所有控件保存。在呈现阶段,页面为每个控件调用Render方法,提供一个文本编写器来编写其输出。 值得注意的是,Page类每次执行这些步骤称为e页。每当出现到服务器的往返行程时,就会初始化、处理和处置页面。 在页面生命周期的每个阶段中,页面会引发事件,我们可以处理这些事件来定制和运行我们自己的代码。对于控件事件,我们将事件处理程序绑定到事件,或者使用“onclick”等属性声明性地绑定,或者在代码中绑定。 aspx和。aspx之间的关系。或者。aspx.vb和ASP。NET运行时类如下图所示。例如,一个名为_Default的新类派生自System.Web.UI.Page。 隐藏,复制Code
public partial class _Default : Page
aspx页面文件又继承了派生的_Default类。 图1 因为.aspx文件是在用户浏览页面时动态编译的,所以它与类文件的关系是通过页面顶部的脚本指令建立的。在一个ASP。NET Web表单中的“@Page”指令(或用户控制文件中的“@Control”)包含指定.aspx文件及其代码隐藏文件关系的属性。例如: 隐藏,复制Code
<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default"EnableEventValidation="false"%>
服务器加载一个ASP。然后在请求完成后将其卸载。页面及其包含的服务器控件负责执行请求并将HTML呈现回客户机。 尽管客户端和服务器之间的通信是无状态的和断开的,这个ASP的主要目标。NET Web表单模型是指客户端必须体验到类似于在自己的桌面上连续执行有状态进程的体验。该模型的另一个目标是帮助像我们这样的开发人员在像Microsoft Visual Studio这样的快速应用程序开发IDE中快速构建Web应用程序。 有状态连续性的假象是由ASP创建的。NET页框架和由页及其控件。在回发时,控件的行为必须像它是从前一个web请求结束时停止的地方开始的一样。 ASP的设计者。Microsoft的NET Page框架使得状态管理的执行相对容易,但是像我们这样的控件和页面开发人员必须了解控件的执行顺序,以达到连续性的效果。这是我们需要从ASP知道的。当asp.net处理Web表单页面时,Web页面的生命周期是一个事件序列。Web服务器上的NET运行时。 ASP.NET中基于事件的编程 首先,让我们讨论一点背景知识。事件模型在Visual Basic和Visual c++中使用MFC开发Windows桌面应用程序时很流行。这与基于顺序过程的模型(用流程图表示)有很大的不同。在事件模型中,每个应用程序状态都是一个对象,事件作为触发器将一个应用程序状态移动到另一个状态。作为对象的状态将我们的焦点从控制流转移到状态的属性。流被降级为事件(触发器),用于从一种状态转换到另一种状态。了解到这种方法的优点,微软扩展了这个模型,并将服务器控件和基于页面的Web表单编程模型引入到ASP.NET中。在这个模型中,应用程序开发人员不需要关心如何从用户界面(GUI)收集输入或将输出(例如,HTML)呈现给用户界面的细节。相反,我们应该关注附加到从ASP接收事件或触发器的UI组件的事件处理程序中的特定于应用程序的行为。网运行时。如前所述,传统上,事件被用作不同组件之间解耦的方法。在ASP的情况下。例如,UI控件(比如按钮)的功能可以与另一个Web应用程序集成,而不需要对UI控件本身进行任何更改(在Visual Studio designer中通过拖放操作)。 web应用程序是客户机服务器应用程序,其中客户机通过internet与服务器分离。对于在服务器上运行以响应用户在浏览器中对Web表单所做更改的事件处理程序代码,控件必须将执行从客户机浏览器移回Web服务器。在ASP。当单击按钮时,服务器控件(如asp:Button)负责通过生成表单回发来处理此问题。随着本文的进行,我们将很快看到所有这些细节。 事件和事件处理 事件是当相关事件发生时发生的通知。事件允许一个对象(发送方)通知其他对象(接收方)发生了一些特殊的事情。事件的一个很好的例子是按钮单击。 本质上,事件处理程序类似于回调。它们之间只有细微的差别。从这个角度看,事件是一种匿名广播,而回调是一种握手。 当我们为ASP的单击事件编写事件处理程序时。NET按钮,我们实际上是在为回调方法编写实现。然而,我们不需要显式地调用事件处理程序。相反,asp.net的Page类。NET Web Forms框架充当通知源,因为它会在正确的时间自动执行我们的事件处理程序方法(程序执行流的控制在ASP。网运行时)。 现在,让我们关注一下事件处理机制。组件在运行时调用我们提供的函数(后期绑定),而不是在编译时调用其名称已知的函数。引发或触发事件意味着调用处理程序。要实现这一点,接收组件的事件(或通知)首先向事件源组件提供一个指向其事件处理程序代码的指针,这个过程名为注册。 事件,代表 要处理事件,ASP。微软的网络设计人员引入了一种新的类型,即委托。委托通常被定义为一个面向对象的函数指针。委托在事件发布服务器和事件订阅服务器之间提供必要的间接层。按照设计,事件的发布者绝对不知道任何订阅者。因此,订阅者的工作是向事件的发布者注册或取消注册自己。因此,委托总是返回void,因为事件发布者不能从事件订阅者的返回值执行任何操作。 如上所述,发布服务器上的事件与特定方法(即订阅服务器上的事件处理程序)之间的绑定使用事件委托完成。ASP。NET page框架在运行时自动为这些方法连接(或连接)适当的委托实例。当我们声明委托时,我们实际做的是定义一个类。 当我们声明性地将事件绑定到自定义事件处理程序时,编译器在这里完成了必要的步骤: 使用与事件处理程序的方法签名完全匹配的签名声明委托对象。使用关键字“event”引用委托对象,因此定义它。定义事件处理程序方法。创建一个委托对象,插入我们想要封装的方法,并向将触发事件的对象注册。 隐藏,/ /第一步复制代码。定义原型的委托类型 //接收方必须实现的回调方法 public delegate void OnClickEventHandler (object sender, EventArgs e); / /第二步。在服务器控制 公共事件OnClickEventHandler点击; / /第三步。受保护,虚拟方法负责 //通知已注册对象的事件 OnSubmit (object sender, EventArgs e){…} 和OnInit: 隐藏,/ /第4步复制代码。负责通知的受保护的虚拟方法 这一点。点击+= new EventHandler(this.OnSubmit); Click是事件的名称。此事件属于OnClickEventHandler类型,这意味着事件通知的所有接收者必须提供一个回调方法,该方法的原型必须与OnClickEventHandler委托的原型匹配。如前面的.aspx页面所示,如果我们保持属性AutoEventWireup="true",那么我们就不必像上面那样编写必要的管道代码。 示例项目介绍 有两个使用相同应用程序的例子,都使用ASP。NET服务器控件按钮和GridView。 没有局部渲染的一种。,而没有ScriptManager/UpdatePanel控件。另一种是局部渲染。 示例是一个简单的应用程序。它允许用户从放置在应用服务器上的“ImportFiles”文件夹中的. csv文件列表中导入内容。如果导入数据的完整性检查发现一切正常,它还允许用户将导入的数据与数据库同步。这两个操作是通过单击“Import”和“Synchronize”按钮启动的。导入和同步是两个不同的步骤,在这个例子中,我们没有添加。csv解析的细节,导入数据的完整性检查,最后,数据库的同步过程;相反,我们用延迟和页面上一个简单的进度动画(busy.gif)来模拟它们。在页面加载事件中,查看文件名属性,只会从“/Importfiles”文件夹中提取最后一个时间顺序的文件名,然后与存储在appSettings>中的LastSync文件进行比较。网页上的章节。配置文件-如果它的时间顺序大于LastSync文件名,它将出现在列表中;否则,它将显示一个红色的错误消息,说明没有文件需要导入。每个类别中最新文件的名称保存在ViewState["AvailableFiles"]中作为一个数据表。 需要注意的是,在同步完成之前,用户可以多次导入同一组文件。因此,如果新的文件集与旧的导入的文件集匹配,就不应该出现提示,因为用户的意图很清楚,他或s他想改正一些错误。当最后一个导入文件名与最后一个同步文件名不匹配时,应用程序会提示用户。提示是:“最后导入的数据尚未同步,将丢失。”继续吗?”如果“/Importfiles”文件夹中有多个同一类别的文件,则只能导入最新未同步的文件。一旦它被同步,就不能重新导入它。在本例中,我们通过禁用按钮控件来实现这一点。禁用按钮后,重新启动操作的唯一方法是刷新整个页面,整个过程从头开始。下图显示了示例应用程序的状态及其与事件的转换: 图1一个 处理网页 下面的部分说明了当用户键入ASP的URL时通常发生的顺序。NET页面(在这个简单的示例中我们没有使用登录页面,但这通常是任何需要身份验证的应用程序的起始页面)。 用户请求默认值。aspx网页在浏览器中。Web服务器(IIS)将此调用转发给ASP。网运行时。ASP。NET运行时然后查找页的程序集,如果不存在程序集,它将从.aspx文件及其关联的代码隐藏文件编译页类。ASP。NET运行时然后执行代码,创建HTML,并将其发送到浏览器。我们可以看到HTML代码使用Fiddler工具拦截流量。请注意,服务器控件被直接的HTML、CSS和JavaScript所取代。浏览器呈现HTML,显示示例中的简单表单,如下图所示: 图2 如页面中所示,它有两个单独的部分(由虚线分隔)—顶部的部分包含可供导入的. csv文件列表。底部部分描述了最近导入的文件列表和最近同步的文件列表的相关信息。当用户单击“导入”按钮时,浏览器会识别出“导入”按钮已被单击。表单的方法是POST,动作在Default.aspx.cs中编码。因此,我们有所谓的回发到原始的.aspx文件。请参阅下面来自Fiddler截获屏幕的快照。图3。显示了一个普通的回发,而图3b显示了一个带有部分呈现的AJAX异步回发,稍后会解释。 图3 图3 b 在接收回发请求后,ASP。服务器上的NET运行时现在对这个页面执行处理,它将经历不同的阶段,并被称为页面生命周期(如前所述)。当用户单击“Import”按钮时,会引发一个事件;这可以在服务器上识别,并调用页面类中的事件处理程序'btnImport_Click'。在模拟的处理延时和进度动画完成后,本例更新了下面部分的相应行,即。、LastImportAgencyFile、LastImportFacilityFile和LastImportLocationFile。然后服务器将整个响应发送给浏览器。请注意3b的响应负载。小于3a。浏览器再次呈现页面以进行普通回发,而PageRequestManager在异步回发的情况下进行DOM更新。现在,用户看到导入已经成功完成,因为底部的最后一个导入文件名与顶部的导入文件名以及当前导入日期时间匹配。ASP。NET使用Web表单中名为剩余viewstate的隐藏字段保存客户端上的状态。当我们在ASP的上下文中考虑事件模型时。值得注意的是,由于用户的各种操作(在本例中,单击“Import”按钮),一个事件在客户机上引发,并在服务器上通过一个委托和page类上的事件处理程序进行处理。 在上面描述的典型场景中,每次往返(称为回发)都会重新创建页面。一旦服务器完成处理并将页面发送到浏览器,它就会丢弃页面信息。 这是保存Web服务器资源和使Web应用程序可伸缩的必要步骤。下一次发布页面时,服务器将重新开始创建page类的新实例,然后再次开始处理它。我们看到ASP。NET Web页面本质上是无状态的——默认情况下,页面的变量和控件的值不会保存在服务器上。然而,为了保持连续性,ASP。NET通过在往返之间保存控制属性来绕过这个限制。在示例中,这是通过保存在视图状态来实现的,这是ASP.NET提供的众多机制之一。我们还使用了hidden <input>字段作为多个标志的占位符,以便在客户端事件处理程序和服务器端事件处理程序之间进行协调。 ASP的状态管理特性的例子。网: 视图状态控件状态隐藏字段cookie查询字符串应用程序状态会话状态配置文件属性 视图状态、控件状态、隐藏字段、cookie和查询字符串都涉及以各种方式在客户端存储数据,而应用程序状态、会话状态和配置文件属性都将数据存储在服务器的内存中。我们不会对这篇文章做进一步的阐述,因为它是一个不同的主题——这里有一篇很好的CodeProject文章参考:ASP.NET状态管理技术的初学者介绍。 ASP。NET还可以检测表单是在第一次被请求时还是在表单被发送回来时(通过检查Page.IsPostBack),这允许我们相应地编程。 (注意:如果我们比较默认值。在这两个示例项目中,我们会注意到在“EventandAjaxExample”中,我们必须使用“EndRequestHandler”来隐藏异步回发的动画显示。对于'EventExample',它不存在,也不需要,因为一个完整的页面刷新自动设置动画显示为'none' - 'style=display: none')。 服务器端页面事件 ASP。NET允许我们在服务器代码中为从浏览器传递的事件设置事件处理程序。假设用户正在与本例中的Web表单页面进行交互,该页面包含一个“Import”(按钮)服务器控件。用户单击“Import”,然后引发一个事件,该事件通过HTTP POST传输到服务器,其中的ASP。NET page框架解释发布的信息,并将引发的事件与适当的事件处理程序相关联,这是我们根据应用程序逻辑定制的处理程序实现。然后框架执行这个定制的处理程序代码:protected void btnImport_Click(object sender, EventArgs e)。NET服务器控件给人的印象是它们在客户机上维护内存,并通过在服务器上引发事件并处理它们来对用户交互作出反应。对于我们这些开发人员来说,我们需要重写虚拟受保护的事件处理程序(在示例中给出),作为定制的一部分来介绍我们的特定于应用程序的代码——其余的由ASP提供。净框架。 下图从概念上展示了这种机制。 图4 ASP。NET处理捕获、传播和解释客户端浏览器上生成的事件的所有机制。我们在一个Web表单页面中创建事件处理程序,我们不需要考虑这种机制,因为它是在后台发生的,并且完全由ASP管理。网络运行时。 请注意,这些类型的Web表单事件需要往返或回发到服务器以进行处理,因此我们应该根据应用程序逻辑选择性地使用它们,并注意性能。 对于服务器控件,某些事件,通常称为“单击事件”,导致Web表单被发布回服务器。另一方面,服务器控件(如文本框控件)中的更改事件会被捕获,但不会立即导致POST。相反,它们由控件缓存,直到下一次发生POST。此时,当在服务器上再次处理该页时,将处理或处理所有挂起的事件。 这是通常的情况,但当情况需要立即发布。支持更改事件的Sserver控件包括自动回复属性。当此属性设置为true时,控件的change事件将导致窗体立即发布,而不等待单击事件。例如,默认情况下,下拉列表控件的onselectedindexchangeevent不会导致页面被提交。但是,通过将控件的“AutoPostBack”属性设置为true,我们指定一旦用户从列表中选择了一个项目,该页面就会被发送到服务器以处理该事件(通过这种方式,我们可以显示城市的邮政编码)。 事件参数 事件在ASP。NET传递两个参数:一个对象(对象发送者)表示引发事件的对象,另一个对象包含任何特定于事件的信息(EventArgs e)。EventArgs,但对于某些控件,它是特定于该控件的类型。例如,对于ImageButton服务器控件,第二个参数的类型是ImageClickEventArgs,它包含关于用户单击的坐标的信息。类似地,对于TreeView控件的按需PopulateNode事件处理程序,第二个参数的类型是TreeNodeEventArgs。 ASP。网页生命周期 前面,我们简要介绍了ASP。NET页面生命周期作为服务器上的不同处理阶段,其中大部分是asp.net的最终结果。网络事件;现在,让我们看看它们发生的顺序。 因为第二个例子是用ASP封装的。NET部分渲染,我已经包括下图的ASP。NET页面生命周期,其中包括AJAX回发和部分呈现。对于有或没有部分呈现的回发,'PreRenderComplete'之后的阶段是不同的nt,如下所述。 图5 部分呈现 让我们更详细地了解一下ASP.NET中的部分呈现在AJAX回发中会发生什么。做一个ASP。NET页面是部分呈现的页面,我们必须首先向页面添加asp:ScriptManager,然后通过使用asp:UpdatePanel控件包装它们来定义独立的可更新区域。当启用部分页面更新时,控件可以异步发送到服务器。异步回发的行为与常规回发类似,因为产生的服务器页执行整个页和控制生命周期。但是,使用异步回发,页面更新仅限于包含在asp:UpdatePanel控件中并标记为要更新的页面区域。服务器只向浏览器发送受影响元素的HTML标记。在浏览器中,客户机是Sys.WebForms。PageRequestManager类执行文档对象模型(DOM)操作,用更新后的标记替换现有的HTML。这是样本的一部分: 隐藏,收缩,复制Code
<body>
<formid="form1"runat="server">
<asp:ScriptManagerID="ScriptManager1"runat="server"EnablePartialRendering="true"AsyncPostBackTimeout="100"/>
<scripttype="text/javascript"language="javascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
</script>
<divclass="Container">
<asp:PanelID="pnlImport"runat="server"Width="100%"CssClass="Page">
<divclass="Container">
<asp:UpdatePanelrunat="server"ID="UpdatePanelDataImportFiles"UpdateMode="Conditional">
<ContentTemplate>
<h1class="Header">
<asp:Labelrunat="server"ID="lblHeading"Text="<%$Resources:EventResources, lblCsvDataImport %>"></asp:Label>
</h1>
<pclass="Label">
<asp:LabelID="lblFiles"runat="server"Text=""></asp:Label>
</p>
<asp:GridViewID="gvFiles"runat="server"AutoGenerateColumns="False"CssClass="Gridview"Width="100%">
<Columns>
<asp:BoundFieldHeaderText="<%$Resources:EventResources, gvFileName %>"DataField="FileName"/>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
UpdatePanel控件简单地添加了一个包围符标记到原始标记。 每当脚本管理器在页面中检测到一个或多个asp:UpdatePanel控件时,它就会发出如下所示的脚本块(您可以使用Fiddler工具验证这一点): 隐藏,复制Code
//<![CDATA[ Sys.WebForms.PageRequestManager._initialize('ScriptManager1',
// document.getElementById('form1'));
Sys.WebForms.PageRequestManager.getInstance()._updateControls(
['tUpdatePanelDataImportFiles','tUpdatePanelSyncInfo'], [], [], 100); //]]>
_initialize方法是客户端Sys.WebForms上的一个静态方法。PageRequestManager对象(参见MicrosoftAjaxWebForms.js)。它创建PageRequestManager类的一个全局实例,并对其进行初始化。这个类充当一个单例,这个单实例稍后可以通过getInstance方法检索,就像第二条语句中所做的那样。上面的第二个语句还向客户端框架注册了一个UpdatePanel控件数组。在我们的示例中,有两个updatepanel (['tUpdatePanelDataImportFiles', 'tUpdatePanelSyncInfo')。通过其ID引用每个服务器端UpdatePanel控件。 这里发生的关键操作在_initialize方法内部。如前所述,在创建类的单例实例之后,代码将初始化它。此时,将为DOM表单对象的提交事件注册一个处理程序。这意味着,每当页面提交表单时,AJAX脚本就会启动并使用XMLHttpRequest放置请求,而不是让请求通过普通的浏览器回发。保留了原始的表单字段集,并附加了一些额外的信息,以方便服务器端脚本管理器。因此,AJAX回发上传的信息比常规的ASP多一点。净回发。 视图状态以及任何其他隐藏字段都将随请求执行并上传到服务器。在返回的过程中,下载了一个更新的Viewstate,以及新的隐藏字段(如果有的话)和一个可能更短的标记——在Fiddler屏幕截图中,参见图3b。在上面,它被突出显示为5,791字节。特别是,响应只包含回发期间修改过的可更新区域的标记。该列表包括触发回发的UpdatePanel控件UpdatePanelSyncInfo。尽管不在示例中,但它将包括任何嵌套面板、页面中任何其他UpdatePanel控件(其中UpdateMode属性设置为“Always”),以及通过编程方式刷新的任何UpdatePanel控件(通过我们的服务器端自定义编码)。 AJAX回发的响应是文本流,如图3b右下角所示。以上。注意在图3b中。在上面,当基于AJAX的ScriptManager和UpdatePanel控件包含在页面中时,我们会看到额外的WebResouce。axd ScriptResource。axd是在您清除浏览器缓存时加载的,并在第一次加载页面。 使用ASP进行部分渲染。NET AJAX,我们需要UpdatePanel控件以及ScriptManager控件。如果页面上包含ScriptManager控件,而UpdatePanel包含任何控件,则可以通过AJAX异步更新UpdatePanel中的控件。 在ASP。净AJAX 为了追踪所有通过Internet Explorer的网络流量,我们将使用您可以从其网站下载的Fiddler HTTP debugger代理应用程序。为此,浏览本文给出的AJAX示例,并查看通过Fiddler会发生什么;我们可以看到,每次调用部分回发事件时,都会发生一个实际的HTTP POST。HTTP POST请求——图3b。,右手边顶部部分,第五行从顶部,包含通常的HTTP头,但它也包括一个我们从未见过: 隐藏,复制Code
x-microsoftajax: Delta=true
这个头是关键字。一旦ScriptManager控件在服务器上标识了这个头,它将检查表单POST中发送的数据,并以客户机的格式向客户机呈现响应,而不是被动地将引用注入到页面输出中脚本的理解。 除了编写对初始页输出的服务和脚本引用外,ScriptManager控件还将初始化客户端功能。客户端PageRequestManager负责跟踪在ScriptManager中注册的控件生成的所有事件。 当一个回发事件在客户端被触发时,PageRequestManager将识别它是否由任何被识别为部分呈现的控件引起。如果是,PageRequestManager将取消回发活动并重新打包。然后,使用客户端类Sys.Net.WebRequest将来自回发事件的新打包数据传输到服务器。头x-microsoftajax: Delta=true将在通过Sys.Net.WebRequest发送到服务器的POST请求中设置。 在服务器端,将通过LoadPostData通知ScriptManager表单POST中的数据。LoadPostData允许各个控件通过表单POST筛选相关信息。这是一个标准事件,不是ASP特有的。净AJAX)。如果我们引用上面图5中的页面生命周期事件,我们将看到LoadPostData在页面上的InitComplete之后立即发生。在LoadPostData中,ScriptManager控件标识导致表单POST的控件以及控件所在的UpdatePanel。 ScriptManager控件现在已经识别了部分回发,并识别了导致回发的控件。ScriptManager控件完全覆盖其主机页的默认呈现方法。现在我们看到,新的Page类引入了自己的格式,用于将控件呈现到页面输出流。 最后,客户端框架从服务器获取异步响应并解析数据。ScriptManager控件已经将所有控件id和新标记打包到响应中,这样客户机框架就可以解析浏览器的文档对象模型(DOM)上的脚本操作,以更新页面内容。如果整个过程是异步发生的,那么浏览器屏幕会快速而安静地更新,而Web页面的用户不会在交互中出现任何停顿或闪烁,从而获得更好的体验。 图6 结合客户端和服务器事件 我们不能用HTML语法为web服务器控件(比如导入按钮服务器控件)指定客户端事件。相反,在服务器代码中使用如下代码在运行时向控件添加事件属性: 隐藏,复制Code
btnImport.Attributes.Add("onclick", "confirmImport('" +
Resources.EventResources.alertImport + "');");
结论 在本文中,我们介绍了ASP中的一些概念。NET Web表单编程模型以及asp.net中的部分呈现。净AJAX回发。稍后,我们分析了在往返或回发期间在客户机和服务器之间传输的有效负载。在asp.net的代码演练期间。基于asp.net Web表单模型的示例应用程序,我们试图理解这种方法的驱动力。Microsoft设计人员对开发模型进行了抽象,使其与Windows桌面开发模型完全相同,并有助于快速应用程序开发(RAD)。如您所见,我们需要理解这个编程模型的设计意图,以便将其应用到Web应用程序中。 最后,注意一下ASP中的限制。NET Web表单模型与部分呈现。例如,在这个模型中,如果同时发生两个部分呈现调用,则杀死最老的调用,为最新的调用腾出空间。如果您需要寻找更智能的启用AJAX的ASP实现。NET Web表单模型,那么请参见以下内容:Gaia Ajax: ASP的一种新方法。进球阿贾克斯,迪诺·埃斯波西托。 最后,请注意,本文并不建议使用ASP。NET Web Form编程模型是开发Web应用程序的最佳可能方法,特别是当我们考虑可测试性和关注点分离时,但是它在某些场景中是足够的,并且有助于快速的程序开发。 参考文献 代表的好莱坞原则介绍代表的第2部分,与代表的事件的实现,用户控件的广泛检查,比较Web表单和ASP。NET MVC,由Dino Esposito比较架构呈现模式,由Shivprasad Koirala实践ASP。NET:文章集合,Peter Vogel &其他来自Microsoft Model View Presenter的Web表示模式(用于在Web应用程序中创建可测试的UI),由让- paul Boodhoo Gaia Ajax: ASP的一种新方法。进球阿贾克斯,迪诺·埃斯波西托 确认 这个特别的话题实际上是和浦那大学的两位暑期学生(Balu Avhad先生和Mayur Potulwar先生)一起动手研究的结果。他们通过使用Fiddler拦截客户端和Web服务器之间的页面流量来帮助我分析有效负载数据。 历史 初始认证于2010年4月13日提交。添加图1。2010年4月15日。 本文转载于:http://www.diyabc.com/frontweb/news19074.html
ASP。NET Web表单模型,部分呈现和事件的更多相关文章
- HTML_创建易用的Web表单
首先创建一个表单域集合fieldset fieldset元素允许Web开发者将主题相关的表单组合在一起 <fieldset></fieldset> 要说明的是本例子中每个表单都 ...
- 使用Visual Studio 2013 从头构建Web表单
在这篇文章中,我将采取VS 2013中特定的模板,也就是没有身份验证的Web表单模板,并说明如何构建这个项目从头开始.在本教程的最后,你会最终有一个模板,内容几乎是一样的使用Web表单模板没有认证(文 ...
- Flask学习之三 web表单
本部分Miguel Grinberg教程的翻译地址:http://www.pythondoc.com/flask-mega-tutorial/webforms.html 开源中国的:http://ww ...
- 基于Flask框架搭建视频网站的学习日志(三)之原始web表单
基于Flask框架搭建视频网站的学习日志(三)1.原始Web 表单 本节主要用于体验一下前端后端直接数据的交互,样例不是太完善,下一节会加入Flash处理,稍微完善一下页面 (备注:建议先阅读廖雪峰老 ...
- “此网页上的某个 Web 部件或 Web 表单控件无法显示或导入。找不到该类型,或该类型未注册为安全类型。”
自从vs装了Resharper,看见提示总是手贱的想去改掉它.于是乎手一抖,把一个 可视web部件的命名空间给改了. 喏,从LibrarySharePoint.WebPart.LibraryAddEd ...
- ASP.NET Web API 管道模型
ASP.NET Web API 管道模型 前言 ASP.NET Web API是一个独立的框架,也有着自己的一套消息处理管道,不管是在WebHost宿主环境还是在SelfHost宿主环境请求和响应都是 ...
- 跟服务器交互的Web表单(form)
使用HTML来构建可以跟服务器交互的Web表单(form),通过给你的form元素添加一个action属性来达到此目的. action属性的值指定了表单提交到服务器的地址. 例如: <form ...
- 基于Extjs的web表单设计器 第七节——取数公式设计之取数公式的使用
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
- 基于Extjs的web表单设计器 第六节——界面框架设计
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
随机推荐
- 1.OpenGL mac开发环境搭建记录
1.安装GLEW 和GLFW,转摘至:https://www.cnblogs.com/pretty-guy/p/11357793.html 2.开始测试,整个工程报错,关键信息如下: code sig ...
- C++STL complex吃书使用指南
说在前面: complex即为复数 使用c++自带的complex类型,首先要有<complex>头文件,还要使用std命名空间 声明方式: complex <T> a: 声 ...
- windows下TOMCAT对内存使用的设置
1.打开TOMCAT目录 E:\备份\apache-tomcat-8.5.50-windows-x64\apache-tomcat-8.5.50\bin catalina.bat----------- ...
- java安全编码指南之:声明和初始化
目录 简介 初始化顺序 循环初始化 不要使用java标准库中的类名作为自己的类名 不要在增强的for语句中修改变量值 简介 在java对象和字段的初始化过程中会遇到哪些安全性问题呢?一起来看看吧. 初 ...
- WinForm使用Setuo Project打包安装包 (附带vs2019 InstallerProjects安装程序)
vs2019 InstallerProjects安装程序地址: 链接:https://pan.baidu.com/s/1K5iDuQT4CBBw2dJjRLqhjg提取码:dfhy 转载至https: ...
- 在Oracle Sql Developer/Sql Plus中查看oracle版本
输入select * from v$version; 执行即可. 此法在Sql plus中执行效果: SQL> select * from v$version; BANNER --------- ...
- sql如何查询不包含中文
SELECT * FROM dbo.表名 WHERE 字段名 NOT LIKE '%[吖-座]%'
- unittest单元测试执行用例的顺序
打印结果如下:
- k8s运行容器之Job(四)
Job 容器按照持续运行的时间可分为两类:服务类容器和工作类容器. 服务类容器通常持续提供服务,需要一直运行,比如 http server,daemon 等.工作类容器则是一次性任务,比如批处理程序, ...
- Win10系统安装Tensorflow-GPU和VSCode构建Tensorflow开发环境
[前言] 1. 最近因为上课需要安装Anaconda和Tensorflow-GPU,Anaconda安装很容易,但Tensorflow-GPU版本的安装较为复杂,因为需要考虑版本匹配的一些问题,很容易 ...