本文主要是介绍IsPostBack深入分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、IsPostBack 介绍 IsPostBack是 Page类有一个 bool类型的属性,用来判断针对当前 Form的请求是第一次还是非第一次请求。当 IsPostBack= true时表示非第一次请求,我们称为 PostBack,当 IsPostBack= false时表示第一次请求。在 asp.net框架内部有很多的场景需要判断 IsPostBack,比如 LoadAllState等操作就需要在 PostBack的时候进行。对于我们自己使用 WebForm进行开发时,经常会在 Page_Load中对 IsPostBack进行判断,因为第一次请求的时候会执行 Page_Load,在非第一次请求的时候也会执行 Page_Load。为什么对同一个 Form有多次请求呢? asp.net中引入了服务器端事件,支持服务器端事件的控件,会发出对当前 Form的请求,这样在很多情形下我们就需要区别是否是对这个 Form的第一次请求。 2、IsPostBack 结论 本人对 .Net的源代码中相关的处理进行的分析得到如下的结论: 结论① 对于使用 Server.Transfer进行迁移时迁移到的页面其 IsPostBack= false。 结论② Post方式如果 Request中没有请求值,即 Request.Form =null则 IsPostBack= false; Get方式如果 Request中没有请求值,即 Request.QueryString =null则 IsPostBack= false。 结论③ 如果QueryString或Form虽然有请求值,但是QueryString或Form中的Key没有“__VIEWSTATE”和 “__EVENTTARGET”和“__VIEWSTATEFIELDCOUNT”,并且没有键为“null”,值以“__VIEWSTATE”开头并且也没有值为“__EVENTTARGET”的键值对,则IsPostBack=false。 结论④ 使用 Response.Redirect方式向自画面迁移时,此时 IsPostBack =false。 结论⑤ 发生跨页提交( CrossPagePostBack),当访问 PreviousPage属性的时候,对于源 Page, IsPostBack=true。 结论⑥ 发生跨页提交( CrossPagePostBack)时目标页面是 IsPostBack= false 结论⑦ 使用 Server.Execute迁移到的页面其 IsPostBack= false。 结论⑧ 在 Page运行期间其对应的 DLL被更新了并且 Page的树结构发生过变化,这种情况下请求时 IsPostBack= false。 可以这样来理解这些结论:一般情况判断 Request中如果没有请求值则 IsPostBack= false。如果有请求值但是不包括 “__VIEWSTATE”等一些特殊的键或值,则 IsPostBack= false(每次请求后 .Net框架会将一些特殊的隐藏域“ __VIEWSTATE ”等返回给客户端)。还有一些特殊的情形是上面的规则不能正确判断的需要特殊处理的,这些情形包括 Server.Transfer, Response.Redirect, CrossPagePostBack, Server.Execute,发生了页面元素变化及重新编译。 一般来说记住上面的结论就可以,如果您有兴趣,或者怀疑请继续看下面的 IsPostBack推论过程。 3、IsPostBack 推论过程 下面是根据 .Net框架中的源代码,来分析 IsPostBack是如何判断出来的。对于这些结论的推断本人做了相关的试验来证明推论的正确性,由于篇幅的原因没有将这些试验代码体现出来。另外不可能将全部的 .Net框架的代码都体现出来,只是将相关的代码片段列出,说明推断的依据。另外由于本人水平有限对 .Net框架的代码理解还存在的不足的地方,请发现后进行指正,谢谢。 public bool IsPostBack { get { if (this._requestValueCollection == null ) { return false ; } if (this ._ isCrossPagePostBack ) { return true ; } if (this _pageFlags [8]) { return false ; } return ( ( (this.Context .ServerExecuteDepth <= 0 ) || ((this.Context .Handler != null ) && (base.GetType () == this .Context .Handler .GetType ())) ) && !this._ fPageLayoutChanged ); } } 我们将每一个 if判断作为一个小节,作如下的分析。 3.1 this._requestValueCollection == null if (this._requestValueCollection == null ) { return false ; } 可以看出 _requestValueCollection等于 null时 IsPostBack就等于 false。 在 Page.ProcessRequestMain(bool , bool ) 中有如下的代码: if (this .PageAdapter != null ) { this ._requestValueCollection = this .PageAdapter.DeterminePostBackMode(); } else { this ._requestValueCollection = this .DeterminePostBackMode(); } PageAdapter.DeterminePostBackMode 最终还是调用了 Page.DeterminePostBackMode ,下面我们看 Page.DeterminePostBackMode 如何实现。 protected internal virtual NameValueCollection DeterminePostBackMode() { if (this .Context.Request == null ) { return null ; } if (this .Context.PreventPostback) { return null ; } NameValueCollection collectionBasedOnMethod = this .GetCollectionBasedOnMethod(false ); if (collectionBasedOnMethod == null ) { return null ; } bool flag = false ; string [] values = collectionBasedOnMethod.GetValues((string ) null ); if (values != null ) { int length = values.Length; for (int i = 0; i < length; i++) { if (values[i].StartsWith("__VIEWSTATE" , StringComparison .Ordinal) || (values[i] == "__EVENTTARGET" )) { flag = true ; break ; } } } if (((collectionBasedOnMethod["__VIEWSTATE" ] == null ) && (collectionBasedOnMethod["__VIEWSTATEFIELDCOUNT" ] == null )) && ((collectionBasedOnMethod["__EVENTTARGET" ] == null ) && !flag)) { return null ; } if (this .Request.QueryStringText.IndexOf( HttpResponse .RedirectQueryStringAssignment, StringComparison .Ordinal) != -1) { collectionBasedOnMethod = null ; } return collectionBasedOnMethod; } 这个函数中返回 null就意味者 IsPostBack= false,将上面函数中每个返回为 null的地方作如下的分析。 3.1.1 this.Context.Request == null if (this . Context.Request == null) { return null ; }this.Context.Request == null 应该只有在异常的情况下会发生,正常情况下会在 HttpRuntime.ProcessRequestInternal 中创建 HttpContext及 HttpRequest对象。 3.1.2 this.Context.PreventPostback if (this . Context .PreventPostback) { return null ; }在 HttpServerUtility.Transfer 中会使用 PreventPostback ,其代码如下: public void Transfer(string path) { bool preventPostback = this ._context.PreventPostback; this ._context.PreventPostback = true ; this .Transfer(path, true ); this ._context.PreventPostback = preventPostback; } 在调用 Server.Transfer进行画面迁移时设置 Context.PreventPostback = ture。此处得出结论①:对于使用 Server.Transfer进行迁移时迁移到的页面其 IsPostBack= false。 |
这篇关于IsPostBack深入分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!