学习笔记(1)在 ASP.NET 网页中不经过回发而实现客户端回调

根据Visual Studio的例子:客户端回调实现 (C#) 示例 ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_aspnetcon/html/2c688b1a-93a4-4dad-b82b-63974bdbb13e.htm

HTML代码

<% @ Page Language="C#" AutoEventWireup="true" CodeFile="ClientCallbackSample.aspx.cs" Inherits="ClientCallbackSample"  %>

<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 
  1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
>

< html  xmlns ="http://www.w3.org/1999/xhtml"   >
< head  id ="Head1"  runat ="server" >
< title > 演示在 ASP.NET 网页中不经过回发而实现客户端回调 </ title >
  
< script  type ="text/javascript" >
    
function LookUpStock()
    
{
        
var lb = window.document.getElementById("ListBox1");
        
        
if(lb.selectedIndex != -1)
        
{
            
var product = lb.options[lb.selectedIndex].text;
            CallServer(product, 
"");
        }

        
else
        
{
            alert(
"请从上面列表中选择一项产品!");
        }

        
    }

    
    
function ReceiveServerData(rValue)
    
{
        Results.innerText 
= rValue;
    }

    
  
</ script >
</ head >
< body >
  
< form  id ="form1"  runat ="server" >
    
< div >
      
< asp:ListBox  ID ="ListBox1"  Runat ="server" ></ asp:ListBox >
      
< br  />
      
< br  />
      
< button  onclick ="LookUpStock()" > Look Up Stock </ button >
      
< br  />
      
< br  />
      Items in stock: 
< span  id ="Results" ></ span >
      
< br  />
      
< br  />
      
< br  />
    
</ div >
        
</ form >
</ body >
</ html >

 

后台CS

using  System;
using  System.Data;
using  System.Configuration;
using  System.Collections;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Web.UI.HtmlControls;

public   partial   class  ClientCallbackSample : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
    
protected System.Collections.Specialized.ListDictionary catalog;
    
protected void Page_Load(object sender, EventArgs e)
    
{
        String cbReference 
= Page.ClientScript.GetCallbackEventReference(this"arg""ReceiveServerData""context");
        String callbackScript;
        callbackScript 
= "function CallServer(arg, context)" +
            
"" + cbReference + "} ;";
        Page.ClientScript.RegisterClientScriptBlock(
this.GetType(),
            
"CallServer", callbackScript, true);

        
//if (!IsPostBack)
        
//{
        
//    Label label = new Label();
        
//    label.Text = "中华人民共和国!";
        
//    form1.Controls.Add(label);
        
//}

        catalog 
= new System.Collections.Specialized.ListDictionary();
        catalog.Add(
"monitor"12);
        catalog.Add(
"laptop"10);
        catalog.Add(
"keyboard"23);
        catalog.Add(
"mouse"17);

        ListBox1.DataSource 
= catalog;
        ListBox1.DataTextField 
= "key";
        ListBox1.DataBind();
    }


    
private string _returnValue;
    
public void RaiseCallbackEvent(String eventArgument)
    
{
        String returnValue;
        
if (catalog[eventArgument] == null)
        
{
            returnValue 
= "-1";
        }

        
else
        
{
            returnValue 
= catalog[eventArgument].ToString();
        }

        _returnValue 
= returnValue;
    }


    
ICallbackEventHandler 成员
}

测试后存在以下问题

  • HTML的LookUpStock函数中的var lb=document.form1[0].ListBox1出错,改为var lb=window.document.getElementById("ListBox1"]才通过,原因常未弄清楚。
  • 按帮助中源代码调试,在不选择ListBox项就点击Look Up Stock按钮时的JS错误是因为默认情况下,ListBox的selectedIndex为-1,现加入一个判断,当用户还未选择 时点击,给一个提示信息
  • 例子中后台CS代码实现了ICallBackEnevtHandler接口,但是存在两个问题是:该接口必须实现的两个方法第一是public void RaiseCallbackEvent(String eventArgument), 注意是void;第二是public string GetCallbackResult()而例子很奇怪,RaiseCallbackEvent本是void的,他它却是返回string,并且例子中也没有实现GetCallbackResult方法, 难道是Microsoft搞错了...., 导致在调试时报错,解决办法,将RaiseCallbackEvent方法改为void类型,并加入了一个全局的成员变量来将客户端传递的字符串eventArgument纪录, 并由GetCallBackResult返回 。
  • ClientScript.GetCallbackEventReference方法的context参数还未明白具体的作用是什么。

在完成以上工作以后,我发现每次点击Look Up stock按钮时,程序仍然都会从PageLoad开始执行,我在想这样和Asp.net正常的回发有什么区别呢?难道就只是欺骗了眼睛,页面看起只是局部刷新而已?于是我 写了一小段代码来测试,在页面第一次加载时(也就是!IsPostback)动态创建了一个Label,给Label的Text指定一个值,在页面回发时不重新创建这个Label,在正常情况下,当产生PostBack时,这个Label肯定是 会不见的,但在这个例子中,动态创建的Label在我点击一次,甚至N次按钮之后,依然好好的显示在浏览器上,得出的结论应该是通种方式实现客户端回调,没有丢失客户端状态,所以这种方式的好处就是 帮助中第一段落:

在 ASP.NET 网页的默认模型中,用户会与页交互,单击按钮或执行导致回发的一些其他操作。此时将重新创建页及其控件,并在服务器上运行页代码,且新版本 的页被呈现到浏览器。但是,在有些情况下,需要从客户端运行服务器代码,而不执行回发。如果页中的客户端脚本维护一些状态信息(例如,局部变量值),那么发送页和获取页的新副本就会损坏该状态。此外, 页回发会导致处理开销,这会降低性能,且会让用户不得不等待处理并重新创建页。若要避免丢失客户端状态并且不导致服务器往返的处理开销,可以对 ASP.NET 网页编码,使其能执行客户端回调。在客户端回调中, 客户端脚本函数会向 ASP.NET 网页发送一个请求。该网页运行其正常生命周期的修改版本 — 初始化页并创建其控件和其他成员,然后调用特别标记的方法。该方法执行代码中编写的处理过程,然后向浏览器返回可 由另一客户端脚本函数读取的值。在此过程中,该页一直驻留在浏览器中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值