• 解决WebControl的doPostBack参数传递问题


     这些天做了一个WebControl,Control支持复杂的交互,有很多的参数通过调用 __doPostBack(id, eventArgument)来和控件交互。doPostBack的用法是,id: 服务器控件的ClientID,eventArgument: 传回服务器的参数。这个参数在服务器端通过IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)来读取,本来事情就这么简单,可是后来由于eventArgument里是任意的数据,就出现了$、:、#、%等字符情况,这就把我开始用“:”来分隔的eventArguemnt里的多过个参数搞faint了。
        于是我就想,把字符串编码一下的了,把分隔符转掉就行了呗,可是后来发现有些数据需要在Client端由JavaScript去读取处理,然后再PostBack,这样就要在服务器端实现JavaScript的escape和unescape两个函数,真是麻烦。后来想,反正就是为了组合和切分字符串嘛,干脆把字符串线性排好,记下每个字串的length。分解的时候使用length来分解出每个字符子串,这样就再也不用care字符串的内容了,也比编码的效率高些。这个方法的原理和数据压缩里的行程码有点类似,只是我这里不能压缩而已。
        于是我在控件和脚本里分别实现了一个StringHelper类,他们具有相同的方法和方法参数调用: 

    C# StringHelper Class#region C# StringHelper Class
    public class StringHelper
    {
        public StringHelper()
        {
        }
     
        // if list = {'a', 'bc', 'def', 'ghij'}; then return "abcdefghijkl$1:2:3:4"
        public static string ArrayToString(params string [] list)
        {
            if ( list.Length <= 0 )
            {
                return string.Empty;
            }
            string strLengthLine = String.Empty;
            string strStringLine = String.Empty;
            for ( int i= 0 ; i < list.Length ; i++ )
            {
                strLengthLine += ":" + list[i].Length;
                strStringLine += list[i];    
            }
            return strStringLine + '$' + strLengthLine.Substring(1);            
        }
     
        public static string ArrayToString(params object [] list)
        {
            string [] strList = new string [list.Length];
            for ( int i=0 ; i < list.Length ; ++i )
            {
                if ( list[i] is string )
                {
                    strList[i] = (string)list[i];
                }
                else
                {
                    strList[i] = Convert.ToString(list[i]);
                }
            }
            return ArrayToString(strList);
        }
     
        // if strStringLine = "abcdefghijkl$1:2:3:4" then return {'a', 'bc', 'def', 'ghij'}.
        public static string [] StringToArray(string strStringLine)
        {
            int index = strStringLine.LastIndexOf('$');
            if ( index == -1 )
            {
                return new string [] {strStringLine};
            }
            string strLengthLine = strStringLine.Substring(index+1);
            string [] aryLength = strLengthLine.Split(new char [] {':'});
            string [] list = new string [aryLength.Length];
            int start = 0;
            for ( int i=0 ; i < list.Length ; ++i )
            {
                int length = int.Parse(aryLength[i]);
                list[i] = strStringLine.Substring(start, length);
                start += length;
            }
            return list;
        }
    }
    #endregion

    JavaScript StringHelper Class#region JavaScript StringHelper Class 
    StringHelper = function() {}
     
    StringHelper.ArrayToString = function()
    {
        if ( arguments.length == 0 )
        {
            throw 'Must have parameters for call me.';
        }
        var strLengthLine = '';
        var strStringLine = '';
        for ( var i=0 ; i < arguments.length ; i++ )
        {
            var str = '' + arguments[i];
            strLengthLine += ':' + str.length;
            strStringLine += str;
        }
        return strStringLine + '$' + strLengthLine.substring(1);
    };
     
    StringHelper.StringToArray = function(strStringLine)
    {
        var index = strStringLine.lastIndexOf('$');
        if ( index == -1 )
        {
            return [strStringLine];
        }
        var strLengthLine = strStringLine.substring(index+1);
        var aryLength = strLengthLine.split(':');
        var list = new Array(aryLength.length);
        var start = 0;
        for ( var i=0 ; i < list.length ; ++i )
        {
            var length = parseInt(aryLength[i]);
            list[i] = strStringLine.substr(start, length);
            start += length;
        }
        return list;
    };
     #endregion
     
       完成了这两个Helper后,我发现还有很多新的用途,有的时候我们需要在ViewState里放上一些多dimension的字符串数组数据的时候,我们也可以用n次(n和数组维度一样)StringHelper.ArrayToString来serialize数据。当然我们也可以序列化对象放到ViewState里,单纯的string的substring操作,效率上比binaryformat要高很多吧。特别是对于ViewState字符串本身就200,300K的页面来说,能省点是点吧。

    posted on 2004-12-11 01:09 birdshome 阅读(957) 评论(3)  编辑 收藏 收藏至365Key 所属分类: ASP.NET 控件开发

    评论
    # re: 解决WebControl的doPostBack参数传递问题   
    eventArgument应该是通过IPostBackEventHandler.RaisePostBackEvent的这个方法获得的吧
    2005-03-07 19:28 | alittlefish
    # re: 解决WebControl的doPostBack参数传递问题   
    是的呀,有什么问题?!
    2005-03-07 22:49 | birdshome
    # re: 解决WebControl的doPostBack参数传递问题   
    StringHelper.ArrayToString = function()
    {
        if ( arguments.length == 0 )
        {
            throw 'Must have parameters for call me.';
        }
        var args = arguments;
        if ( args.length == 1 && __typeof__(args[0]) == 'Array' )
        {
            args = arguments[0];
        }
        var strLengthLine = '';
        var strStringLine = '';
        for ( var i=0 ; i < args.length ; i++ )
        {
            var str = '' + args[i];
            strLengthLine += ':' + str.length;
            strStringLine += str;
        }
        return strStringLine + '$' + strLengthLine.substring(1);
    };

         修复bug,原来那个版本居然不能接收Array作为参数,还叫ArrayToString,狂晕。
     
         BTW: __typeof__参看这里
    http://www.cnblogs.com/birdshome/archive/2005/02/26/99564.html

  • 相关阅读:
    字符串转换整数
    list、tuple、dict加*星号
    字符串
    整数反转
    字符串分割函数
    核密度图(直方图的拟合曲线)
    不同缺失值的删除方法
    Z字形变换
    最长回文字串
    寻找两个有序数组的中位数
  • 原文地址:https://www.cnblogs.com/zhuor/p/331729.html
Copyright © 2020-2023  润新知