Lets say I have a asp.net webforms website, and I have a paged gridview. Inside the gridview there are links to other pages in the site, these links may be the only links in the entire site to this content. Currently google and other search engines can probably only follow the links that appear on the first page since the gridview pager generates links like:
<a href="javascript:__doPostBack('GridTest','Page$2')">2</a>
So google would never be able to load the other pages to crawl the links.
I need a quick and dirty way for google to index all of the pages that might be hidden behined these javascript links.
I have thought about creating a link with the visibility turned off in the css that will load the gridview with all records visible and no paging. Would this be a good workaround?
If I did have this hidden link how could I prevent the search engine from indexing that page (since I would not want normal visitors to get to it), but still follow and index the pages it links to.
Anyone got any ideas? Thanks for your help.
I liked Colin's idea. I am already using a custom pager control, so I can control the paging links. In order to implement his suggestion I created a control adapter for link buttons which will allow it to render the href attribute if you give it one, and put the postback javascript in the OnClick (but it makes it so you can't use the OnClientClick property at the same time as the href).
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.Adapters;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Adapters;
/// <summary>
/// This adapter allows us to specify the href attribute and have it rendered on the page.
/// When the href is specified the postback javascript will go into the onclick. The javascript will
/// cancel the href so it will post back like normal , but for people without javascript
/// the link should work, and search crawlers should be able to index the links
///
/// Styles that you can set like Font-Bold and Font-Underline are not going to work
/// you will need to use the style attribute, or set it in css
///
/// </summary>
public class LinkButtonAdapter : WebControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
LinkButton linkButton = (LinkButton)Control;
if (linkButton != null)
{
writer.WriteBeginTag("a");
writer.WriteAttribute("id", linkButton.ClientID);
if (!string.IsNullOrEmpty(linkButton.ToolTip))
{
writer.WriteAttribute("title", linkButton.ToolTip);
}
if (!string.IsNullOrEmpty(linkButton.CssClass))
{
writer.WriteAttribute("class", linkButton.CssClass);
}
if (!string.IsNullOrEmpty(linkButton.Attributes["style"]))
{
writer.WriteAttribute("style", linkButton.Attributes["style"]);
}
if (linkButton.Enabled)
{
if (!string.IsNullOrEmpty(linkButton.Attributes["href"]))
{
//if the user has set the href render it, and render the javascript in the onclick
//this will negate the client click script so be careful
writer.WriteAttribute("href", linkButton.Attributes["href"]);
string ClientScript = Page.ClientScript.GetPostBackClientHyperlink(linkButton, "");
if (!string.IsNullOrEmpty(ClientScript))
{
writer.WriteAttribute("onclick", ClientScript + ";return false;");
}
}
else
{
writer.WriteAttribute("href", Page.ClientScript.GetPostBackClientHyperlink(linkButton, ""));
if (!string.IsNullOrEmpty(linkButton.OnClientClick))
{
writer.AddAttribute(HtmlTextWriterAttribute.Onclick, linkButton.OnClientClick);
}
}
}
else
{
writer.WriteAttribute("disabled", "disabled");
}
writer.Write(HtmlTextWriter.TagRightChar);
//apparently link buttons can contain other controls, who knew
//when they are databound, and you have the expression in between the
//tags it gets created as a LiteralControl
//the behavior for linkbuttons seems to be to overwrite whatever
//you set in the text propery with what is in between the begin and end tags
//
//Unless you have a databound control, then the text and the inner text seems
//to be concatenated together, which seems weird
//
//Also sometimes it generates literalcontrols, but removes them, and sometime it leave them
//but only if you have another non literal control inside
//
//I don't want to try to emulate this right now it is too confusing.
//Just don't use the text and the inner html at the same time, and I am leaving all controls
//that have been added
foreach (Control c in linkButton.Controls)
{
if (c is LiteralControl)
{
linkButton.Text = ((LiteralControl)c).Text;
}
else if (c is DataBoundLiteralControl)
{
linkButton.Text = ((DataBoundLiteralControl)c).Text;
}
else
{
c.RenderControl(writer);
}
}
writer.Write(linkButton.Text);
writer.WriteEndTag("a");
Page.ClientScript.RegisterForEventValidation(linkButton.UniqueID);
}
}
}
Then put this in your browsers file:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.LinkButton"
adapterType="LinkButtonAdapter" />
</controlAdapters>
</browser>
</browsers>