1

I have a page with a big GridView and a HyperLinkfield bound to one of the columns, with two parameters, in the following format:

 <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>

String DataNavigateUrlFormatString="~/adm/Clipping/Publicidade/Cadastro/ValorPrograma.aspx?programa={0}&amp;nome={1} is replaced by DataNavigateUrlFields="id,nome". And all is fine...for some of the rows. On the other hand, values don't get replaced and the URL is incomplete.

So I went to the database to check if there was some data inconsistency, and pulled data from a field being normally replaced on the GridView and for another which isn't being replaced.

Data is consistent in database. Result 1 isn't being replaced at all when formink the hyperlinkfield

Any ideas?

Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
marquito
  • 885
  • 11
  • 29
  • 1
    How about UrlEncoding the database strings? – Hanno Feb 25 '13 at 14:36
  • Is there a way to do that inside the grid itself or do I need an event hook? – marquito Feb 25 '13 at 14:37
  • But I cannot see any related reason for that behaviour. – marquito Feb 25 '13 at 14:38
  • I think you need to do that in the RowDataBound event. As for the reason why do it, my guess is, ç and/or õ are invalid characters for an URL and cause the entire string to be left out. See also http://stackoverflow.com/questions/1386262/should-i-use-accented-characters-in-urls – Hanno Feb 25 '13 at 14:40
  • @Hanno the funny thing is that, from the database picture I showed, record #1 is the problematic one and the record with ç and õ works **fine**. – marquito Feb 26 '13 at 12:34

2 Answers2

2

As suggested by Hanno's comments and replied by jadarnel27's actual Reply, the problem is related to URL character encoding (specifically in this case the encoding of the : character).

To solve this issue, I suggest using a TemplateField instead of the HyperLink field, as follows

        <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>

The key concept is using HttpUtility.UrlEncode() in the template itself instead of calling the RowDataBound event.

With that done, the database data will be properly encoded before making up the URL and it just works.

Community
  • 1
  • 1
marquito
  • 885
  • 11
  • 29
0

I agree with Hanno's statement in the comments, this is likely due to invlaid URL characters.

This is one way you could encode the characters from the RowDataBound event:

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;
    }
}

You'll need to have something like this in the markup for your GridView, in order to hook it up to the event handler:

OnRowDataBound="yourGridView_RowDataBound"
Community
  • 1
  • 1
Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
  • I posted my answer in C#, because I don't see that you specified a language. If you're using VB.NET, the response is similar, but let me know if you need help translating it. – Josh Darnell Feb 25 '13 at 16:12
  • I'm using C#, but your answer didn't work for me. It gives me an "Object reference not set" on the `Server.UrlEncode(rowView["id"].ToString());`, probably because the rowView object is null (can't debug because it's a production system here). Just note that I've made the necessary changes for it to work but may have missed something. – marquito Feb 26 '13 at 13:04
  • Found the problem, which was indeed an encoding problem (specifically, the `:` char on the URL. My approach was different, though. I preferred to use the HyperlinkField as a TemplateField an make up the URL on the aspx page, as @jadarnel27's example did not work for me. I'll accept your answer because it hits the spot, but the solution needs improvement. – marquito Feb 26 '13 at 13:08
  • @marquito Good catch, Anytime you do processing in the RowDataBound event on things like this, you have to make sure you're working with a DataRow (and not a header or footer). I left out the check for that, which is why you were getting null. The updated code should work, although it sounds like your solution is more elegant than this. – Josh Darnell Feb 26 '13 at 13:32
  • 1
    I wouldn't say "elegant", as mixing presentation and code processing has never been a favourite of mine. You believe I should also answer the question? – marquito Feb 26 '13 at 13:38
  • @marquito Ah, that's a good point. It certainly takes less code than this, though, which sometimes is a plus =) Feel free to add your solution as another answers, there are no rules against that here. Out of curiosity, did my updated code work without errors? – Josh Darnell Feb 26 '13 at 13:42