为啥 HyperLinkField 替换某些 URL 中的字段而不替换其他 URL?

Posted

技术标签:

【中文标题】为啥 HyperLinkField 替换某些 URL 中的字段而不替换其他 URL?【英文标题】:Why is HyperLinkField replacing fields in some URLs and not in others?为什么 HyperLinkField 替换某些 URL 中的字段而不替换其他 URL? 【发布时间】:2013-02-10 17:38:34 【问题描述】:

我有一个页面,其中一个大 GridView 和一个 HyperLinkfield 绑定到其中一个列,带有两个参数,格式如下:

 <asp:HyperLinkField DataNavigateUrlFields="id,nome" DataNavigateUrlFormatString="~/adm/Clipping/Publicidade/Cadastro/ValorPrograma.aspx?programa=0&amp;nome=1" HeaderText="Valores" InsertVisible="False" NavigateUrl="~/adm/Clipping/Publicidade/Cadastro/ValorPrograma.aspx"                 Text="Ajustar valores">
        <ItemStyle ForeColor="#339933" />
 </asp:HyperLinkField>

字符串DataNavigateUrlFormatString="~/adm/Clipping/Publicidade/Cadastro/ValorPrograma.aspx?programa=0&amp;amp;nome=1DataNavigateUrlFields="id,nome" 替换。 一切都很好...对于某些行。另一方面,值不会被替换,并且 URL 不完整。

所以我去数据库检查是否有一些数据不一致,并从GridView 上通常被替换的字段和未被替换的另一个字段中提取数据。

有什么想法吗?

【问题讨论】:

UrlEncoding 数据库字符串怎么样? 有没有办法在网格本身内部做到这一点,还是我需要一个事件挂钩? 但我看不出这种行为的任何相关原因。 我认为您需要在 RowDataBound 事件中执行此操作。至于这样做的原因,我的猜测是,ç 和/或õ 是 URL 的无效字符,并导致整个字符串被遗漏。另见***.com/questions/1386262/… @Hanno 有趣的是,从我展示的数据库图片来看,记录 #1 是有问题的记录,而带有 ç 和 õ 的记录很好 【参考方案1】:

根据Hanno 的comments 的建议和jadarnel27 的实际Reply 的回复,问题与URL 字符编码有关(特别是在这种情况下是: 字符的编码)。

为了解决这个问题,我建议使用TemplateField而不是HyperLink字段,如下

        <asp:TemplateField HeaderText="Valores" InsertVisible="False">
            <ItemTemplate>
                <asp:HyperLink ID="HyperLink1" runat="server" 
                    NavigateUrl='<%# "~/adm/Clipping/Publicidade/Cadastro/ValorPrograma.aspx?programa=" + HttpUtility.UrlEncode(Eval("id").ToString()) + "&nome=" + HttpUtility.UrlEncode(Eval("nome").ToString()) %>'
                    Text="Ajustar valores"></asp:HyperLink>
            </ItemTemplate>
            <ItemStyle ForeColor="#339933" />
        </asp:TemplateField>

关键概念是在模板本身中使用HttpUtility.UrlEncode(),而不是调用RowDataBound 事件。

完成后,数据库数据将在构成 URL 之前被正确编码,并且它可以正常工作。

【讨论】:

我同意这是一种更简洁的解决问题的方法。我会记住这一点!【参考方案2】:

我同意Hanno's 声明in the comments,这可能是由于嵌入的URL 字符。

这是一种可以对 RowDataBound 事件中的字符进行编码的方法:

protected void yourGridView_RowDataBound(Object sender, GridViewRowEventArgs e)

    if(e.Row.RowType == DataControlRowType.DataRow)
    
        i = 0; // the ordinal of the column you need to encode

        DataRowView rowView = (DataRowView)e.Row.DataItem;
        string id = Server.UrlEncode(rowView["id"].ToString());
        string nome = Server.UrlEncode(rowView["nome"].ToString());

        string newURL = String.Format("~/adm/Clipping/Publicidade/Cadastro/ValorPrograma.aspx?programa=0&amp;nome=1", id, nome);

        e.Row.Cells[i].Text = newURL;
    

您需要在GridView 的标记中包含类似的内容,以便将其连接到事件处理程序:

OnRowDataBound="yourGridView_RowDataBound"

【讨论】:

我在 C# 中发布了我的答案,因为我没有看到您指定了一种语言。如果您使用的是 VB.NET,则响应类似,但如果您需要翻译帮助,请告诉我。 我正在使用 C#,但您的回答对我不起作用。它在Server.UrlEncode(rowView["id"].ToString()); 上给了我一个“未设置对象引用”,可能是因为 rowView 对象为空(无法调试,因为它是这里的生产系统)。请注意,我已对其进行了必要的更改以使其正常工作,但可能遗漏了一些东西。 发现了问题,这确实是一个编码问题(特别是 URL 上的 : 字符。不过我的方法不同。我更喜欢使用 HyperlinkField 作为 TemplateField 来弥补aspx 页面上的 URL,因为 @jadarnel27 的示例对我不起作用。我会接受您的回答,因为它恰到好处,但解决方案需要改进。 @marquito 很好,每当您在 RowDataBound 事件中处理此类事情时,您必须确保您使用的是 DataRow(而不是页眉或页脚)。我省略了检查,这就是你得到空值的原因。更新后的代码应该可以工作,尽管听起来您的解决方案比这更优雅。 我不会说“优雅”,因为混合演示和代码处理从来都不是我的最爱。你认为我也应该回答这个问题吗?

以上是关于为啥 HyperLinkField 替换某些 URL 中的字段而不替换其他 URL?的主要内容,如果未能解决你的问题,请参考以下文章

在gridview使用HyperLinkField传递多个参数

仅对具有 DataBinding 事件的对象提供数据绑定表达式支持。System.Web.UI.WebControls.HyperLinkField 没

[UOJ513]UR #19清扫银河

为啥检查没有被优化

为啥 DSB 不刷新缓存?

为啥应用 tranwrd 函数后最后一个字符被删除