关于 GridView,HyperLinkField,UrlEncode

我假定你是碰到了和我相同的问题,搜索标题中这几个关键字来到这篇文章的。

简单的描述一下这个有点挠头的问题,就是对于 GridView 中的 HyperLinkField 列,MS 并没有像 BoundField 那样提供 UrlEncode/HtmlEncode 之类相关的属性设置。可实际运用中,你很可能碰到需要在 URL 中传中文参数的问题。Google 出来的网页表明,西方人也会因为一些特殊字符(比如 &)碰到同样的问题。当然相比西方人,CJK 圈子里更普遍一些。

目前看到的文章给出的方案大都是将 HyperLinkField 转化为 TemplateField 之后,手动用 HttpUtility.UrlEncode 方法处理数据绑定。代码会增多,看起来也不太雅观。而且如果你反悔或者想调整字段时,从 TemplateField 也不能自动转回 HyperLinkField。

Google 出来的网页中,有一些网友跟我同样的想法,希望 MS 能够在 .net 2.0 下个版本(也就是 .net 3.x)中提供一个这样的常用属性,并且已经有人向 MS 提交了“bug 报告”。MS 的答复应该令不少人失望:为了在版本升级中保持 backward-compatibility,MS 不会添加这样的属性。

(顺便多句嘴,backward-compatibility 这个词,国内有人译作“向前兼容”,也有人译作“向后兼容”,呵呵,很有意思的一件事,都有点道理,“以前”是指 before now,“向前看”却是 look forward。)

MS 说明 backward-compatiblity 的 blog 上,很多网友表达了跟我类似的疑惑:既然 .net 各个版本之间可以互不影响的独立工作,那就没有必要去“过分”地追求 100% backward-compatibility。当然,为了大家不至于重新学习,做到尽可能兼容就可以了,但以前写的程序,就还让它们在原来的 .net framework 上运行就好了。

而至于版本迁移,决策者准备迁移之前,就应该考虑好迁移的优点和缺点,就像 PetShop 从 .net 1.x 迁移到 2.0 改动不可谓之不大,但为了利用 2.0 最新的技术,它那样去做了,到底值不值得,那就是决策者的算盘了。

好了,上面对于多数人来说都是废话,来主要的吧:

下面这段代码给你一个新选择,避免将 HyperLinkField 转换为 TemplateField ,但同时实现了 UrlEncode。

 

    public static void HyperLinkFieldUrlEncodeHack(GridView gridView)
    {
        if (gridView == null)
        {
            return;
        }
        gridView.RowDataBound += delegate(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType != DataControlRowType.DataRow)
            {
                return;
            }
            for (int i = 0; i < gridView.Columns.Count; i++)
            {
                DataControlField field = gridView.Columns[i];
                if (field is HyperLinkField)
                {
                    log.Debug(e.Row.RowType.ToString());
                    TableCell td = e.Row.Cells[i];
                    if (td.Controls.Count > 0 && td.Controls[0] is HyperLink)
                    {
                        HyperLink hyperLink = (HyperLink)td.Controls[0];
                        HyperLinkField hyperLinkField = (HyperLinkField)field;
                        if (!String.IsNullOrEmpty(
                            hyperLinkField.DataNavigateUrlFormatString))
                        {
                            string[] dataUrlFields = new string
                                [hyperLinkField.DataNavigateUrlFields.Length];
                            for (int j = 0; j < dataUrlFields.Length; j++)
                            {
                                object obj = DataBinder.Eval(e.Row.DataItem,
                                    hyperLinkField.DataNavigateUrlFields[j]);
                                dataUrlFields[j] = HttpUtility.UrlEncode(
                                    (obj == null ? "" : obj.ToString()));
                            }
                            hyperLink.NavigateUrl = String.Format(
                                hyperLinkField.DataNavigateUrlFormatString, 
                                dataUrlFields);
                        }
                    }
                }
            }
        };
    }

 

我想你该知道怎么来使用这段代码吧?

posted on 2008-04-18 20:01  破宝  阅读(327)  评论(0编辑  收藏  举报

导航