tags:

views:

669

answers:

4

I have the following column in a GridView, and my problem is that it only renders the text "Download", not a URL.

<asp:HyperLinkField DataNavigateUrlFields="ArchiveLocation" Text="Download" DataNavigateUrlFormatString="{0}" />

When I bind a DataTable with one row to the grid, the ArchiveLocation in that row contains the value:

"~/Common/Forms/ExportStream.aspx?path=C:\Development\Chase\Exports\ChaseExport-090312073930.zip".

A: 

You have to tell it what to bind to when using a templateField

<asp:HyperLinkField DataNavigateUrlFields="ArchiveLocation" Text="Download" DataNavigateUrlFormatString="{0}"  NavigateUrl='<%#Eval("ArchiveLocation")%>' />
Glennular
That gives me the error: " Databinding expressions are only supported on objects that have a DataBinding event. System.Web.UI.WebControls.HyperLinkField does not have a DataBinding event."
ProfK
A: 

I would debug the databinding process by adding the onitemdatabound event handler, setting a breakpoint in it and then looking at your DataItem to be sure it is what you are expecting.

The hyperlink field is in a row template and not a header or footer right?

Jeff Martin
A: 

Use the NavigateUrl only if you want the same URL for all records.

It appears that the HyperLinkField renders text only if there is a colon in the field's value. Remove the colon and you will see hyper links. I don't know why yet.

Apparently, the OnDataBindField method calls CrossSiteScriptingValidation.IsDangerousUrl which considers ':' dangerous on your behalf:

internal static bool IsDangerousUrl(string s)
{
    if (string.IsNullOrEmpty(s))
    {
        return false;
    }
    s = s.Trim();
    int length = s.Length;
    if (((((length > 4) && ((s[0] == 'h') || (s[0] == 'H'))) && ((s[1] == 't') || (s[1] == 'T'))) && (((s[2] == 't') || (s[2] == 'T')) && ((s[3] == 'p') || (s[3] == 'P')))) && ((s[4] == ':') || (((length > 5) && ((s[4] == 's') || (s[4] == 'S'))) && (s[5] == ':'))))
    {
        return false;
    }
    if (s.IndexOf(':') == -1)
    {
        return false;
    }
    return true;
}
Ruslan
A: 

A work around would be to use a template field and encode the colon to its hexadecimal representation, which would be %3A.

<asp:TemplateField>
    <ItemTemplate>
        <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("ArchiveLocation","{0}").Replace(":", Server.UrlEncode(":")) %>' Text="Download"></asp:HyperLink>
    </ItemTemplate>
</asp:TemplateField>

When retrieving the value from the query string variable collection it will be automatically decoded.

string path = Request.QueryString["path"];
Phaedrus