技术开发 频道

ASP.NET 是怎样实现连续性假象的?


【IT168技术文档】

  对开发者而言,以往对于一个提交按钮的点击回发,或者说 HTML form 提交的处理往往是在另一个页面中处理,将 form 的 target 指向该页面。(当然在一个页面中也是可以完成的,但大部分人习惯于两个页面)
  在 ASP.NET 中,这一过程被处理成和 Windows 程序类似的过程,Button 的点击、form 被提交这个事件被 ASP.NET “包装”成一个服务器事件,也就是 Button 的 Click 事件。从生命周期来看,Button 控件被加载的流程如下: LoadPostData 这一步可以从 Request.Form 集合中找到 Button 的 name 值(只有被点击的 Button 会在 Request.Form 集合中生成一个 name-value 对);过了 Load,在 RaisePostBackEvent 这一步,将触发 Button 的 Click 事件。
  我们再分析特别的情况:Button 在 HTML 中是可以引起 form 的提交的,也就是可以引起页面回发;但其他的,如 LinkButton (对应于 HTML 的 A 元素),DropDownList (对应于 HTML 的 SELECT)等,则并不会自动引起回发。这种情况下,ASP.NET 使用了又一个技巧来保证这一假象继续成立:打开含有 LinkButton 的一个 ASP.NET 生成的 HTML 页面代码,可以找到两个隐藏字段,一个叫 __EVENTTARGET,一个叫 __EVENTARGUMENT,再往下找到一段脚本:
  function __doPostBack(eventTarget, eventArgument) {   var theform;   if (window.navigator.appName.toLowerCase().indexOf("netscape") >-1) {   theform = document.forms["Form1"];   }   else {   theform = document.Form1;   }   theform.__EVENTTARGET.value = eventTarget.split("$").join(":");   theform.__EVENTARGUMENT.value = eventArgument;   theform.submit();   }
  再看看 LinkButton 生成的代码:
  LinkButton
  
  如果你做过网页中的客户端脚本的话,应该知道,当点击这个“LinkButton”时,实际上是通过客户端脚本将它的名字和若干参数(比如 Calendar 需要传递一些参数, LinkButton 没有传参数的必要)设置到两个隐藏字段中,并在脚本中提交了表单。
  继续看服务段的流程:LoadPostData 会看到这两个隐藏字段中的值,但并不马上解析;依然是过了 Load,在 RaisePostBackEvent 这一步解析这两个字段中的值,触发相应控件的事件。
  我们最后分析一下 CheckBox 或者 DropDownList 之类的 AutoPostBack 属性:如果 AutoPostBack 为 true,则在向客户端输出时,加入上面的 __doPostBack 式的回发;如为 false,则不加入这样的立即回发脚本,而是等待有其他可以引起回发的控件(比如 Button, LinkButton 等)回发后,在 RaisePostDataChanged 中触发 CheckBox 的 CheckedChanged 事件,DropDownList 的 SelectedIndexChanged 事件;在 RaisePostBackEvent 时继续分析其他引起回发的事件。
  微软把复杂的 Web 模型简化成一个传统 Windows 程序员易于接受的模型,大大降低了 Web 开发的门槛。但尽管如此,微软无法改变 Web 的“无状态”、“断续”的实质,所以不要将所有 Windows 程序开发的经验都一古脑运用到 Web 开发当中。了解了其内在机理,有助于 Windows 程序员避免这些“武断”的错误。
0
相关文章