您所在的位置: 程序员家园 -> 家园博客 ->
 
在哪里摔倒
就在哪里自己爬起来

用户登录

查  找

最新评论

最新留言

常用网站

网易邮箱 GMAIL  

百度搜索 MSDN

霏凡软件 BT精品

影视帝国 射 手 网

电驴下载 全 库 网

友情连接

茄菲的窝 冰冰博客

枫叶飘零 玫  瑰

ACEN 云 豹 子

统  计



Dict.CN 在线词典, 英语学习, 在线翻译
利用“不经过回发而实现客户端回调”解决“回发或回调参数无效”的问题
狼子 发表于 2008-10-17 16:55:00 阅读全文 | 回复(0) | 引用通告 | 编辑

回发或回调参数无效,这个问题一直拖着,从用ASP.NET 2.0开始,用了各种各样的办法解决,到前一段时间,我使用的是Ajax的方法读取数据,客户端使用select控件和HiddenField控件结合的办法,服务器端从HiddenField中读取的数据回发

今天开始看MSDN中性能一节,跟着页面链接转着转着,看到这一节“在 ASP.NET 网页中不经过回发而实现客户端回调”的链接,切换过去,好东西。。。不知道为什么以前没有看这个,郁闷

记录几个链接:

如何:在 ASP.NET 网页中实现回调:http://msdn.microsoft.com/zh-cn/library/ms366518(VS.80).aspx

在 ASP.NET 网页中不经过回发而实现客户端回调:http://msdn.microsoft.com/zh-cn/library/ms178208(VS.80).aspx

客户端回调实现 (C#) 示例:http://msdn.microsoft.com/zh-cn/library/ms178210(VS.80).aspx

具有验证实现的客户端回调示例:http://msdn.microsoft.com/zh-cn/library/ms366515(VS.80).aspx

如何:通过对字符串应用 HTML 编码在 Web 应用程序中防止脚本侵入:http://msdn.microsoft.com/zh-cn/library/a2a4yykt(VS.80).aspx

下面说利用这个解决问题的办法,用两个级联的DropDownList做例子,大类使用服务器端控件DropDownList,小类使用客户端控件select,使用HiddenField记录小类的当前选项,这个做法是前一段时间用Ajax做的时候想到的,这里不同的是,使用Ajax时,我在客户端读取数据,用这个方法呢,就是不回发实现回调,直接在本页面的服务器端脚本里取小类对应大类的全部数据

我说得很乱,乱七八糟,直接看文件好了,那个,已经没的好解释的了,文件里面都是带注释的,具体的东西,看MSDN是最好的,我想如果我说,也是搬MSDN的东西。。。要说明的是,在这里,我从服务器端返回的数据是对应大类的全部小类,这个字符串里的数据形式是这样子的:小类一编号|小类一名称+小类二编号|小类二名称

TwoDdl.aspx

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>测试DropDownList无回调</title>
    <script type="text/ecmascript">
    function GetSmallClass()
    {
        var ddl = document.getElementById("DropDownList1");
        var myid = ddl.options[ddl.selectedIndex].value;
        CallServer(myid, "");
    }
   
    function ReceiveServerData(rValue)
    {
        document.getElementById("hfAll").value = rValue;
        SetSmallClassItem();
    }
   
    function SetSmallClassItem()
    {
        var ddl, obj, str, text, value, index, indexForOp, strForOp, sValue;
        obj = document.getElementById("hfAll");
        ddl = document.getElementById("smallClass");
        if(obj == null || ddl == null) return;
       
        //取所有小类的字符串
        str = obj.value;
        ddl.options.length = 0;
       
        //开始分解每一个选项
        indexForOp = str.indexOf("+");
        if(indexForOp == -1) return;
       
        while(indexForOp > -1)
        {
            strForOp = str.substring(0, indexForOp);
            str = str.substring(indexForOp + 1);
          
            index = strForOp.indexOf("|");
            text = strForOp.substring(0, index);
            value = strForOp.substring(index + 1);
           
            ddl.options[ddl.options.length] = new Option(value, text);
           
            indexForOp = str.indexOf("+");
        }
        //最后一个选项
        index = str.indexOf("|");
        if(index > -1)
        {
            text = str.substring(0, index);
            value = str.substring(index + 1);
            ddl.options[ddl.options.length] = new Option(value, text);
        }
       
        //初始化当前选项
        sValue = document.getElementById("hfSID").value;
        if(sValue != "")
        {
            ddl.value = sValue;
            if(ddl.selectedIndex == -1)
            {
                ddl.selectedIndex = 0;
                SetValue(ddl);
            }
        }
        else
        {
            //把现在的选项设置到HiddenField中记录
            SetValue(ddl);
        }
    }
   
    //把每一个小类选项都设置到TextBox记录
    function SetValue(ddl)
    {
        var obj;
        obj = document.getElementById("hfSName");
        if(obj) { obj.value = ddl.options[ddl.selectedIndex].text; }
       
        obj = document.getElementById("hfSID");
        if(obj) { obj.value = ddl.options[ddl.selectedIndex].value; }
    }
   
    addLoadEvent(SetSmallClassItem);
   
    function addLoadEvent(func)
    {
        var oldonload = window.onload;
        if(typeof window.onload != 'function') { window.onload = func; }
        else { window.onload = function() { oldonload(); func(); } }
    }
  </script>
</head>
<body>
    <form id="form1" runat="server">
    <p>
        大类:
        <asp:DropDownList ID="DropDownList1" runat="server" OnDataBound="DropDownList1_DataBound"></asp:DropDownList>
    </p>
    <p>
        小类:
        <select id="smallClass" onchange="SetValue(this);"></select>
        <asp:HiddenField ID="hfAll" runat="server" /><asp:HiddenField ID="hfSName" runat="server" /><asp:HiddenField ID="hfSID" runat="server" />
    </p>
    <p>
        <asp:Button ID="Button1" runat="server" Text="提交" OnClick="Button1_Click" />
        <br />
        <asp:Literal ID="Literal1" runat="server"></asp:Literal>
    </p>
    </form>
</body>
</html>

TwoDdl.aspx.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 TwoDdl : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
{
    protected static System.Collections.Specialized.ListDictionary bClass;
    protected static DataTable sClass;
    protected String returnValue;

    protected void Page_Load(object sender, EventArgs e)
    {
        #region 添加客户端脚本callbackScript
        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);
        #endregion

        //不回大类下拉菜单的onchange事件
        DropDownList1.Attributes.Add("onchange", "GetSmallClass();");

        //初始化两个分类的数据
        if (!IsPostBack)
        {
            IniClass();
            bClassDataBind();
        }
    }

    #region 每次大类数据更新后,重调小类,服务器端只更新hfAll,客户端调用SetSmallClassItem设置选项
    protected void DropDownList1_DataBound(object sender, EventArgs e)
    {
        hfAll.Value = SetSmallClassHiddenText(DropDownList1.SelectedValue);
    }
    #endregion


    #region 模拟提交
    protected void Button1_Click(object sender, EventArgs e)
    {
        Literal1.Text = "大类:" + DropDownList1.SelectedValue + "(" + DropDownList1.SelectedItem.Text + ")<br />小类:" + hfSID.Value + "(" + hfSName.Value + ")";
    }
    #endregion

    #region 实现ICallbackEventHandler接口的两个方法
    //实现 ICallbackEventHandler 接口的 RaiseCallbackEvent 方法
    public void RaiseCallbackEvent(String eventArgument)
    {
        returnValue = SetSmallClassHiddenText(eventArgument);
    }

    //实现 ICallbackEventHandler 接口的 GetCallbackResult 方法
    public String GetCallbackResult()
    {
        return returnValue;
    }
    #endregion

    #region 初始化两个DropDownList控件
    private void IniClass()
    {
        bClass = new System.Collections.Specialized.ListDictionary();
        bClass.Add(12, "积木");
        bClass.Add(10, "魔方");
        bClass.Add(23, "拼板");
        bClass.Add(17, "智力");

        sClass = new DataTable();
        sClass.Columns.Add("bClassID", typeof(Int32));
        sClass.Columns.Add("sClassID", typeof(Int32));
        sClass.Columns.Add("sClassName", typeof(string));
        sClass.Rows.Add(new Object[] { 12, 1, "乐高" });
        sClass.Rows.Add(new Object[] { 12, 2, "蓝猫奇迹" });
        sClass.Rows.Add(new Object[] { 12, 3, "滚珠轨道" });
        sClass.Rows.Add(new Object[] { 10, 4, "二阶魔方" });
        sClass.Rows.Add(new Object[] { 10, 5, "三阶魔方" });
        sClass.Rows.Add(new Object[] { 10, 6, "四阶魔方" });
        sClass.Rows.Add(new Object[] { 23, 7, "万能方块" });
        sClass.Rows.Add(new Object[] { 23, 8, "新思维金字塔" });
        sClass.Rows.Add(new Object[] { 23, 9, "立体方块" });
        sClass.Rows.Add(new Object[] { 17, 10, "数字数独棋" });
        sClass.Rows.Add(new Object[] { 17, 11, "字母数独棋" });
        sClass.Rows.Add(new Object[] { 17, 12, "数和棋" });
        sClass.Rows.Add(new Object[] { 17, 13, "加七游戏" });
    }
    private void bClassDataBind()
    {
        //绑定大类
        DropDownList1.DataSource = bClass;
        DropDownList1.DataTextField = "value";
        DropDownList1.DataValueField = "key";
        DropDownList1.DataBind();
    }
    #endregion

    #region 取大类选项对应的所有小类,用+链接后返回
    private string SetSmallClassHiddenText(string bClassID)
    {
        string returnValue = "";
        try
        {
            DataRow[] drs;
            drs = sClass.Select("bClassID=" + bClassID);
            if (drs.Length > 0)
            {
                foreach (DataRow dr in drs)
                {
                    if (returnValue.Equals(""))
                    {
                        returnValue += dr["sClassID"].ToString() + "|" + dr["sClassName"].ToString();
                    }
                    else
                    {
                        returnValue += "+" + dr["sClassID"].ToString() + "|" + dr["sClassName"].ToString();
                    }
                }
            }
        }
        catch (NullReferenceException)
        {
            returnValue = "-1";
        }
        return returnValue;
    }
    #endregion
}

发表评论:

    昵称:
    密码:
    主页:
    标题:
Powered by Oblog.