Solved

How to create a hyperlink in gridview in C# code behind?

Posted on 2014-02-28
6
5,760 Views
Last Modified: 2014-03-01
I am a total newbie and I am trying to modify someone else's code.
The .aspx page has a gridview cotnrol on it. In the c# code behind, several columns for the gridview are defined, and rows are created ... all dynamically. That all works fine.

There is a column for "Email". I want the email to link to a page and pass an id that is unique to the email (which I know what it should be).
So the link would be, for example:
<a href="/mypage.aspx?id=123">test@test.com</a>

Open in new window


The column is defined in the code behind:
                dcField = new DataColumn();
                dcField.DataType = System.Type.GetType("System.String");
                dcField.ColumnName = "Email";
                dcField.ReadOnly = false;
                dcField.Unique = false;
                dtRequests.Columns.Add(dcField);

Open in new window


In the code behind, the column is filled ... I tried this but of course all I see in the grid view is the HTML, not a link:
string emailLink = "<a href=\"/mypage.aspx?id=" + formDataId.ToString() + "\">" + htFormData["Email"] + "</a>";
                drRequest["Email"] = emailLink;

Open in new window

               

I know this is a common question on the web but I am such a newbie that I don't understand what is being said. I need to know exactly what code I need to add/change in the code behind so that the link will be displayed. I'm not looking for examples or links to other solutions. I need the exact code.

Please let me know if you need any other info.
Thanks.
0
Comment
Question by:alicia1234
  • 3
  • 3
6 Comments
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 500 total points
ID: 39896667
In your case the following would probably be the easiest solution.

There should be a line somewhere that binds the data to the grid, something like:
GridView1.DataBind();

Open in new window

Just before that, add this line (substituting the name of your grid for GridView1):
GridView1.RowDataBound += new GridViewRowEventHandler(GridView1_RowDataBound);

Open in new window

The handler that is used by the line above, is defined as follows:
        void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
            int intEmailCol = 1; // set to correct column, starting at 0
            if (e.Row.RowType == DataControlRowType.DataRow && // skip header/footer
                e.Row.Cells[intEmailCol].Text.StartsWith("&lt;a href")) { // don't just decode all text in all columns, in this case we know what we want to show: <a href...
                e.Row.Cells[intEmailCol].Text = Server.HtmlDecode(e.Row.Cells[intEmailCol].Text);
            }
        }

Open in new window

The first line in there holds a constant, in my small test datatable "Email" was the second column so I set the column index to 1. For you this will probably be a different value, depending on your other columns. If it's the last column you could use:
int intEmailCol = e.Row.Cells.Count - 1

Open in new window

Point is, this will only be done for the Email column. Because if you start doing this for all columns (as some examples on the web suggest) it could be a security risk, writing out a script tag in your html for example.
0
 

Author Comment

by:alicia1234
ID: 39897184
You are my hero! ;-) That worked perfectly. Just one little tweak I am wondering about. Is there a way for me to actually pass the number of the email column to the event handler?
And if I did want more than one column to be a link (which I don't but good to know), if I could pass the column number, then would I just "call" the event handler once for each column? And FYI ... this is only used by registered, paying, logged in, "naive" users ... and the ID is not a user ID or anything like that. If someone were to try messing with the ID number, they really couldn't do any harm. ;-)
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39897237
Nice!

Well no not really an argument to the handler but perhaps just make it a class variable (move the declaration of int intEmailCol outside the function), if you want a number of columns that class variable could be for example
List<int> mEmailCols = new List<int>();

Open in new window

and you could fill it with
mEmailCols.Add(dtRequests.Columns.IndexOf(dcField));

Open in new window

after your code where you add the fields to the dtRequests.Columns, but before the DataBind call again.

The event handler could then process all column indices in the List:
        void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
            foreach (int intEmailCol in mEmailCols) {
                if (e.Row.RowType == DataControlRowType.DataRow && // skip header/footer
                    e.Row.Cells[intEmailCol].Text.StartsWith("&lt;a href")) { // don't just decode all columns, in your case we know what we want to show: <a href...
                    e.Row.Cells[intEmailCol].Text = Server.HtmlDecode(e.Row.Cells[intEmailCol].Text);
                }
            }
        }

Open in new window

If you do it for multiple columns, remember that the check for "<a href" is there, if you need other content to be shown as well, take out that check.

Then, at some point, if you want to take it to the next level (because this is a bit of a 'quick & dirty hack'), look into defining TemplateFields on your DataGrid: http://msdn.microsoft.com/en-us/library/aa479353.aspx (I haven't tried it for this type of data yet but it should be easy to do, if you want I'll have a look later on).
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 
LVL 35

Expert Comment

by:Robert Schutt
ID: 39897248
Well. why wait... I had a look and you could define your grid as follows:
        <asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="false">
            <Columns>
                <asp:BoundField DataField="id" HeaderText="id" />
                <asp:BoundField DataField="Email" HeaderText="Email Address" HtmlEncode="false" />
            </Columns>
        </asp:GridView>

Open in new window

The actual columns would differ for you but the important part is AutoGenerateColumns="false" and HtmlEncode="false" because from what I read, auto generate is what 'switches on' the encoding by default so this is the way to prevent that.

After making sure you have a backup of your project I would say lose the event handler and this is the way to go even though it's a bit more work.
0
 

Author Comment

by:alicia1234
ID: 39897251
Great. Thank you SO much! ;-)
0
 

Author Closing Comment

by:alicia1234
ID: 39897252
Exactly what I needed to know!
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Media.Imaging 1 18
Javascript to set controls visibility 5 32
ASP.NET MVC -Add authentication 2 20
VB.NET 2008 - SQL Timeout 9 23
We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
In this video I am going to show you how to back up and restore Office 365 mailboxes using CodeTwo Backup for Office 365. Learn more about the tool used in this video here: http://www.codetwo.com/backup-for-office-365/ (http://www.codetwo.com/ba…

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now