[续]和Postback说再见

2024-02-15 12:08
文章标签 再见 postback

本文主要是介绍[续]和Postback说再见,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

“和Postback说再见”上篇在此 作者提供的1.1中代码,和服务端生成的ScritpClient脚本,在此下载。 [续]和Postback说再见  

为了将此新特新运用在ASP.NET1.1中,我们来挖掘一下,在.NET2.0中到底是如何实现的。
以下是跟踪过程:用birdsome介绍的方法点击more info前打开在下一步按Alt->v->u->b然后点击more info:
<button id="btn" onclick="javascript:WebForm_DoCallback('__Page',document.all['DropDownList1'].value,UpdateInfo,null,null,false)">More Info</button>
从此处可以知道button已经绑定上了由GetCallbackEventReference产生的脚本。在这个版本中并没有这个脚本的名字还是叫WebForm_DoCallback,Never Mind!继续,F11……
< script src="/ExperienceAspx2.0/WebResource.axd?a=s&amp;r=WebForms.js&amp;t=632430413780000000" type="text/javascript"></script>
我们还发现在页面中系统加上了上面这段脚本。WebResource.axd是一个在ASP.NET中新的内置于HTTP的处理中。用它把脚本程序包含到页面中。这个handler确保把所有的控件或者页面的Callback引用脚本包含进来。并且,webResource.axd确保所有的WebForm_DoCallback和WebForm_InitCallback成功的被执行。
下面我们就揭开它的真面目:
 
这个版本的WebResource.axd中包含的函数有:
function WebForm_PostBackOptions(eventTarget, eventArgument, validation, validationGroup, actionUrl, trackFocus, clientSubmit)
function WebForm_DoPostBackWithOptions(options)
function WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync)
function WebForm_CallbackComplete()
function WebForm_InitCallback()
function WebForm_ReEnableControls()
function WebForm_ReDisableControls()
function WebForm_FireDefaultButton(event, target)
function WebForm_GetScrollX()
function WebForm_GetScrollY()
function WebForm_SaveScrollPositionSubmit()
function WebForm_SaveScrollPositionOnSubmit()
function WebForm_RestoreScrollPosition()
function WebForm_TextBoxKeyHandler()
我们只研究其中的WebForm_DoCallback,和WebForm_CallbackComplete,其他完整的代码我将在提供打包下载。
在原文中作者给出了两个不要直接调用WebForm_oCallback的理由,第一是可以通过Client Script Mangner来管理用其GetCallbackEventReference方法来实现客户端的脚本,第二由于,WebForm_DoCallback不是Page API的所以在以后的版本中不能保证它不改名字,并且,如果其有新的修改也不会有对外公布的必要。
从该代码中可以发现它不仅适用于ie,对其他浏览器也提供了支持。它使用了一个COM对象从特定的URL中来接受发送数据。
然后在HTTP传送数据时是选择POST,还是GET是取决于数据的大小。如果大于2K的数据则采用POST。HTTP请求包含3个基本元素:__CALLBACKID,__CALLBACKPARAM,和发送的数据包。__CALLBACKID中包含目标地址,而__CALLBACKPARAM则是携带者服务段方法需要的参数。发送的数据包氏通过WebFrom_InitCallback方法来连接并且附加HTTP命令中。以上代码详细呈现了该实现过程。
如何使用Script Callback IN ASP.NET 1.1
到目前为止,我想我们把它搬到1.1中来使用也不是非常困难的事情。下面根据我的实践结果来讨论如何在Script Callback。
首先介绍我第一次错误的使用方法。
根据2.0的思路,第一感觉就是我把它的那些系统生成的脚本,我自己给他挖掘出来,添加到客户端,然后在后台添加自己的GetCallbackReference(),并实现RaiseCallback()两个方法,不就是一个1.1版本的Script Callback。
首先我根据vs2005的简单的msdn,以及跟踪其返回值,写了个假的GetCallbackReference();代码如下:
 
本来想对其6个参数作详细介绍的,可是考虑到这不是正确的方法,所以在此就不在叙述,如果想知道的朋友可以查看msdn2.library.com(这里的还是旧版本),或者查看vs2005的对象浏览器。
类似2.0中在Page_Load作如下引用:
String callbackRef = this.GetCallbackEventReference(this,"document.all['DropDownList1'].value","MoreInfo",null,null,false);
btn.Attributes["onclick"] = String.Format("javascript:{0}",callbackRef);
 
并将我提供的的所有2.0中的系统脚本加到客户端中,可是调试的时候确发现,我手工添加的脚本和服务端添加的脚本存在的区别就在于编译的顺序不一样,当编译客户端的脚本的时候服务端的脚本还没有生成,也就是说,它无法调用theForm,postUrl等变量,于是我想到,是不是可以在后台在Page_Init的时候以编程的方式加入到客户端,必须确保它是在服务端脚本加入后而执行的,至于放在Page_Init中还是在Page_PreRender()我不是很清楚。
好错误的方法讨论到此,下面介绍作者的方法,也是正确的方法,起初我想用2.0中原有的脚本也许更强大,更完善。作者的方法很简单。简单的实现了xmlHTTP的客户端与服务端的通信,但是不支持其它版本的浏览器。
后台ScriptCallback.aspx.cs:

 
在1.1中的效果如下:
 
 Figer4.JPG
 
 
至此我们实现了在ASP.NET1.1中的无postback的和服务端的提交获取数据。原理就是利用了xmlHTTP。不过我们还是更期待在2.0中来使用该功能。
思考与问题
整个研究学习过程中,我逃避了两点。第一,对2.0中的脚本程序没有做细致的分析,它到底是如何运行的,第二,如果我一定要用服务端的脚本,我如何通过后台把脚本以程序方式加入到客户端,并且在呈现客户端页面后再调用。如果你有兴趣的话,可以和我一起研究哦。
个人觉得,在该文章上发布的时候已近有人提出来这样做的安全性,我觉得很有道理,如此所有的通信就相当于明码在这样传来传去,对于传一些比较重要的数据的时候这样做是很危险的,我也不是很清楚2.0中有没有对这个问题提供其它可靠的有安全保障的方法。但如果把这个方法用在简单的更具客户的不同要求而时时地对页面中某些元素进行验证,少量的数据绑定,这可以算是一个不错的解决方法!如果有大量数据要通过此方法和服务端通信,是不是可以加一个loading bar,让更新数据部分的元素停止操作,而用户仍然可以操作其它控件这样的二次开发,我还没有尝试,我想不久就会尝试。所以做gon功能简单,要把功能做出漂亮的UI就很难,如果要在漂亮的UI上加上user experience就是难上加难啊!
作者信息
在此注册blog一直没有发表任何文章,我一直觉得自己水平还不够,这次下了决心,参考msdn的文章,然后加上自己总结实践,凑成了这篇文章,希望能给各位有所赏,有所析,有所用。小弟在此献丑了,我想我以后主要还是这种方式来提交和大家一起学习进步。这样我自己也能有很大收获,也能给大家带来一点内容。
关于我自己,我现在就读杭州电子科技大学的通信工程学院,2005年就是大三下了,不知道这儿大学生多么?希望能和各位交个朋友。
生活博客:http://spaces.msn.com/members/rbmnetatmsn/
常用Email:rbmxxx at hotmail.com
Connect me!

 

function  MoreInfo1()       var  selectedID  =  document.all[ " DropDownList1 " ].value;       var  xml  =  DoCallback( " ScriptCallback.aspx " ,selectedID);       var  o  =  xml.responseText.split( " , " );      e_ID.innerHTML  =  o[ 0 ];      e_UserName.innerHTML  =  o[ 1 ];      e_Password.innerHTML  =  o[ 2 ];      e_Authority.innerHTML  =  o[ 3 ];      e_BlogName.innerHTML  =  o[ 4 ];      e_Email.innerHTML  =  o[ 5 ];  function  DoCallback(url,params)       var  pageUrl  =  url  +  " ?callback=true&param= "  +  params;       var  xmlRequest  =  new  ActiveXObject( " Microsoft.XMLHTTP " );      xmlRequest.open( " POST " ,pageUrl, false );      xmlRequest.setRequestHeader( " Content-Type " " application/x-www-form-urlencoded " );      xmlRequest.send( null );       return  xmlRequest;  }
其中e_ID,e_UserName等类似分别是我呈现表格的第二列的cell的ID。
  public  class  ScriptCallback : System.Web.UI.Page      {        protected System.Web.UI.HtmlControls.HtmlButton btn;        protected System.Web.UI.WebControls.DropDownList DropDownList1;                private void Page_Load(object sender, System.EventArgs e)        {            if(IsCallback())               return;                        if(!IsCallback())               this.PopulateList();                        string callbackRef = "MoreInfo1()";            btn.Attributes["onclick"= String.Format("javascript:{0}",callbackRef);        }                private bool IsCallback()        {            if(Request.QueryString["Callback"!= null)            {               string param = Request.QueryString["param"].ToString();               Response.Write(RaiseCallbackEvent(param));               Response.Flush();               Response.End();               return true;            }            return false;        }                  private void PopulateList()        {            DataProvider dp = new DataProvider();            DropDownList1.DataTextField = "UserName";            DropDownList1.DataValueField = "ID";            DropDownList1.DataSource = dp.GetAllUserConfig().Tables[0];            DropDownList1.DataBind();        }        string RaiseCallbackEvent(string eventArgument)        {            string[] buf = new string[6];            DataProvider dp = new DataProvider();            DataTable dt = dp.GetAllUserConfig().Tables[0];            DataRow[] dr =dt.Select("ID = " + eventArgument);            buf[0= dr[0]["ID"].ToString();            buf[1= dr[0]["UserName"].ToString();            buf[2= dr[0]["Password"].ToString();            buf[3= dr[0]["Authority"].ToString();            buf[4= dr[0]["BlogName"].ToString();            buf[5= dr[0]["Email"].ToString();              return String.Join(",", buf);          }  
前台的脚本如下:
protected  string  GetCallbackEventReference(System.Web.UI.Control control,  string  argument,  string  clientCallback,  string  context,  string  clientErrorCallback,  bool  useAsync)         {            string[] ReturnValue = new string[6];            if(control.ID != null)               ReturnValue[0= control.ID.ToString();            else               ReturnValue[0= "'__Page'";              ReturnValue[1= argument;            ReturnValue[2= clientCallback;                        ReturnValue[3= context!=null?context:"null";            ReturnValue[4= clientErrorCallback!=null?clientErrorCallback:"null";            ReturnValue[5= "false";                        return String.Format("WebForm_DoCallback({0})",String.Join(",",ReturnValue));                    }
var  __callbackObject  =  new  Object(); function  WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) {     re  =  new  RegExp( " //x2B " " g " );      var  postData  =  __theFormPostData  +                  " __CALLBACKID= "  +  eventTarget  +                  " &__CALLBACKPARAM= "  +  escape(eventArgument).replace(re,  " %2B " );      if  (__nonMSDOMBrowser) {          var  xmlRequest  =  new  XMLHttpRequest();          if  (pageUrl.indexOf( " ? " !=  - 1 ) {             xmlRequest.open( " GET " , pageUrl  +  " & "  +  postData,  false );         }          else  {             xmlRequest.open( " GET " , pageUrl  +  " ? "  +  postData,  false );         }         xmlRequest.setRequestHeader( " Content-Type " " application/x-www-form-urlencoded " );         xmlRequest.send( null );         response  =  xmlRequest.responseText;          if  (response.charAt( 0 ==  " s " ) {              if  (eventCallback  !=  null ) {                 eventCallback(response.substring( 1 ), context);             }         }          else  {              if  (errorCallback  !=  null ) {                 errorCallback(response.substring( 1 ), context);             }         }     }      else  {          var  xmlRequest  =  new  ActiveXObject( " Microsoft.XMLHTTP " );         xmlRequest.onreadystatechange  =  WebForm_CallbackComplete;         __callbackObject.xmlRequest  =  xmlRequest;         __callbackObject.eventCallback  =  eventCallback;         __callbackObject.context  =  context;         __callbackObject.errorCallback  =  errorCallback;          var  usePost  =  false ;          if  (pageUrl.length  +  postData.length  +  1  >  2067 ) {             usePost  =  true ;         }          if  (usePost) {             xmlRequest.open( " POST " , pageUrl, useAsync);             xmlRequest.setRequestHeader( " Content-Type " " application/x-www-form-urlencoded " );             xmlRequest.send(postData);         }          else  {              if  (pageUrl.indexOf( " ? " !=  - 1 ) {                 xmlRequest.open( " GET " , pageUrl  +  " & "  +  postData, useAsync);             }              else  {                 xmlRequest.open( " GET " , pageUrl  +  " ? "  +  postData, useAsync);             }             xmlRequest.setRequestHeader( " Content-Type " " application/x-www-form-urlencoded " );             xmlRequest.send();         }     } }
可见在该版本中比作者原文的WebForm_DoCallback有了很大的改进。

这篇关于[续]和Postback说再见的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/711350

相关文章

再见!XP!微软举行“欢送Windows XP暨Windows 8.1体验会”

Windows XP 即将在 4 月 8 日终止支持,你淮备好了吗? 随著 Windows XP 的退役时间越来越近,Microsoft 希望所有使用者都能够尽快转移到最新的 Windows 8.1 系统。因此 Microsoft 于 28 日开始一连三天,假台北信义区香堤大道举行“欢送 Windows XP 暨 Windows 8.1 体验会”,通过 Windows 8.1 的体验、教学,欢送已

推荐系统三十六式学习笔记:结束语 |遇‘荐‘之后,江湖再见

目录 结束语如相问,写专栏如来故,不负卿如临渊,如履冰 结束语 毋庸置疑,好的事情总会叫来,而当她来晚时,亦不失为一种惊喜。学习的快乐也总是如此,得以亨受的人是幸运的,更幸运的是,这是一种可以通过努力而获得的快乐。人世间可以通过努力而获得的快乐可不多哦!愿惜之,共勉! 好了,专栏终于写完了,所以我可以承认了:写专栏的过程还是很痛苦的。如果要说整个过程中的一些感悟和心路,那就概括

【七月】再见,不负遇见

Happiness can be found, even in the darkest of times, if one only remembers to turn on the light! 即使在最黑暗的时刻,幸福也有迹可循,只要你记得打开一盏灯。 If life is divided into two episodes, the first is “hesitance-free”, w

强!34.1K star! 再见Postman,新一代API测试利器,功能强大、颜值爆表!

1、引言 在当今的互联网时代,API(应用程序编程接口)已经成为连接不同软件系统的桥梁。作为一名开发者,掌握API测试技能至关重要。市面上的API测试工具琳琅满目,今天我们要介绍的是一款开源、跨平台的API测试工具——Insomnia。 2、Insomnia介绍 Insomnia是一款功能丰富、易使用、强大且开源的API测试工具,广泛应用于API的开发、测试与调试。它以其简洁的界面、强大的功

论坛开发者总结:再见2013,你好2014!

转自:http://www.cocoachina.com/gamedev/misc/2014/0102/7644.html 在跨年的时候,我和你一样听着电视里的各种欢呼声,看着时针分针不慌不忙地走向0点,有点兴奋有点怅然有点对过往的追忆也有对未来的期许,但在0点钟声敲响的时候,不管过往如何,都信心满满地对自己说了声--你好2014! 对于开发者来说,2013年移动游

GDK,李跳跳,再见了!还是这两款软件用起来爽!

软件链接:GDK,李跳跳,再见了!还是它们用起来舒服!  智慧岛 智慧岛(原名:禅师)是一款专为安卓用户设计的应用体验提升工具。它通过一系列智能化功能,让用户在使用各种应用时更加便捷和高效。可以去除软件的开屏广告和内置广告,软件内置规则,有想去的广告软件内并没有内置规则的话,可在软件内云端搜索。 自动跳广告:智慧岛能够自动识别并跳过应用启动页的广告,为用户节省宝贵的时间,同时提升应用的流

Python数据科学 | 是时候跟Conda说再见了

本文来源公众号“Python数据科学”,仅用于学术分享,侵权删,干货满满。 原文链接:是时候跟Conda说再见了 1 简介 conda作为Python数据科学领域的常用软件,是对Python环境及相关依赖进行管理的经典工具,通常集成在anaconda或miniconda等产品中供用户日常使用。 但长久以来,conda在很多场景下运行缓慢卡顿、库解析速度过慢等问题也一直被用户所诟病,且由

算法金 | 再见!!!梯度下降(多图)

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 接前天 李沐:用随机梯度下降来优化人生! 今天把达叔 6 脉神剑给佩奇了,上 吴恩达:机器学习的六个核心算法! ——梯度下降 1、 目标 梯度下降优化算法的概述,目的在于帮助读者理解不同算法的优缺点。 2、 开整 梯度下降法在优化神经网络中的应

再见,我的HTML!华丽转身!

转眼之间,我已经来到兄弟连20天了!但是我仍然还依稀记得当时自己拖着行李来到兄弟连的样子,想不到这么快就在兄弟连扎下了根,并且荣幸的成为了兄弟连的一员。也终于看见了兄弟连这帮玩命的兄弟们了,也看到了那些可爱的,可敬的,有责任心的,有魅力的老师们了,心中不由的沉寂了多年的热情重新被点燃。看到兄弟连的兄弟们这样认真并且刻苦玩命的学习,仿佛突然之间我回到了高中时代,那是的我们也是这样,充满激情,充满斗志

再见2020,启航2021

2020这一页匆匆翻过 我们仍习以为常地把年份写为2020 我们还总是不经意地回望这一年 我们见证袋鼠云的成长 看到数字化进程的加快 数栈DTinsight升级4.0 云原生数据中台迈上一大步...... 这是我们想说再见的一年 这是我们无法忘记的一年 我们用关键词总结回顾这一年 来看,袋鼠云的2020: 01 2020年,金融、政企、文旅、新零售、制造、教育、IT..