用于 SEO(搜索引擎优化)的自定义 DataGrid 分页
一个关于如何自定义 .NET DataGrid 以进行 SEO (搜索引擎优化) 的简短示例。
引言
如果您在访问量很大的网页上使用 DataGrid
,并且它们仅显示信息而不用于编辑数据,那么高速度、小尺寸可能就是您所需要的。
标准的 DataGrid
并没有针对搜索引擎索引进行优化,因为它使用 JavaScript 回发来跳转到下一页。此外,您的用户也可能在浏览器中禁用了 JavaScript。我们将研究如何实现一个自定义的 DataGrid 分页器,该分页器包含“< 上一页”和“下一页 >”链接,并用标准的锚标记替换回发按钮。
背景
由于互联网流量的大部分由搜索引擎产生,因此让尽可能多的相关页面被抓取并被索引是大多数网站管理员的主要关注点。我认为 DataGrid
是 ASP.NET 开发人员可用的最强大的控件之一。但是,它的使用有两个缺点:
- 它会生成臃肿的 Viewstate,这可能导致搜索引擎下载无效数据,从而跳过页面,因为某些爬虫只读取网页的最顶部部分。
- 由于使用了 JavaScript 回发,分页器不会创建对爬虫友好的链接,这些链接并未针对爬虫进行优化。
实现自定义分页可能比自己编写自定义代码更容易,但实现自定义解决方案可能是让更多页面被抓取的答案,因为您将使用锚标记而不是回发来处理分页。
使用代码
代码有两个方面:
DataGrid
的自定义分页。- 表单的
Page_Load
事件中的自定义分页。
所有自定义分页器的操作都在 DataGrid
的 ItemCreated
事件中完成。需要记住的主要一点是,分页器由一个 Label
控件(未链接因此是当前页码)和几个 DataGridLinkButton
控件组成,这些控件是活动按钮。这些 DataGridLinkButton
是我们想要用标准 HTML 锚标记替换的“罪魁祸首”。
行内提供了更具描述性的注释。
Datagrid_ItemCreated 事件
Private Sub CustomGrid_ItemCreated(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) _
Handles CustomGrid.ItemCreated
If e.Item.ItemType = ListItemType.Pager Then
Dim Pager As TableCell = CType(e.Item.Controls(0), TableCell)
Dim myEnumerator As IEnumerator = Pager.Controls.GetEnumerator()
'Will hold the value of the position of the label
' control in the enumerated list of controls
Dim labelPos As Int16
'Flag to indicate that you have reached the label control in the list
Dim blTag As Boolean = False
Dim strObj As String
Dim litTemp As Literal
'Counter value to hold the index of the last control in the Pager
Dim y As Int16
resumeHere:
y = 0
While (myEnumerator.MoveNext())
Dim myObject As Object = myEnumerator.Current
y += 1
'Have we reached the Label control
If myObject.GetType().Equals(GetType(Label)) Then
If blTag = False Then
labelPos = CType(myObject, Label).Text - 1
blTag = True
End If
'Have we reached DataGridLinkButton control
ElseIf myObject.GetType.ToString.Equals("System." & _
"Web.UI.WebControls.DataGridLinkButton") Then
'Remove the currnt control from the Pager
Pager.Controls.Remove(myObject)
'Create a new Literal control with our anchor tag that we
'will be using instead of the JavaScript Postback
litTemp = New Literal
'Build your custom anchor tag
litTemp.Text = "<a href=" & chr(34) & _
"thispage.aspx?page=" & _
CStr(CInt(CType(myObject, LinkButton).CommandArgument) - 1) _
& chr(34) & ">" & _
CType(myObject, LinkButton).CommandArgument & "</a>"
'Add the new Literal control to the current location in the Datagrid
Pager.Controls.AddAt(y - 1, litTemp)
'You have to reload the Enumerator as
'we have made changes to the Pager
myEnumerator = Pager.Controls.GetEnumerator()
'Loop back and start the enumeration from
'the beginning of the Pager
GoTo resumeHere
End If
End While
'Create the Literal control that will be used to
'create the "Next >" button in the pager
Dim lbNext As New Literal
'Build your custom anchor tag
lbNext.Text = "<a href=" & chr(34) & _
"thispage.aspx?page=" & labelPos + 1 _
& chr(34) & "> Next ></a>"
'Create the Literal control that will be used
'to create the "< Prev" button in the pager
Dim lbPrev As New Literal
'Build your custom anchor tag
lbPrev.Text = "<a href=" & chr(34) & _
"thispage.aspx?page=" & _
labelPos - 1 & chr(34) & ">< Prev </a>"
'Get the number of controls in the Pager and
'subtract 1 from the number as it is 0 based
Dim endPagingIndex As Integer = (Pager.Controls.Count - 1)
'Insert "< Prev" page link if the Datagrid
'is on a page other than the first page listed in the Pager
If (labelPos > 0) Then
endPagingIndex += 1
'Ad the control to the Pager at the start
'of the Pager which is has an index of 0
Pager.Controls.AddAt(0, lbPrev)
End If
y = CType(sender, DataGrid).PageCount - 1
'Insert "Next >" page link if the Datagrid is
'on a page other than the last page available in the Pager
If (labelPos < y) Then
'Ad 1 to the number of controls in the Pager
'as we want to add the control to the end of the Pager
endPagingIndex += 1
'Ad the control to the Pager at the start
'of the Pager which is has an index of "endPagingIndex"
Pager.Controls.AddAt(endPagingIndex, lbNext)
End If
'Additional Pager text added to a Label control
Dim InfoText As Label = New Label
InfoText.ID = "it"
InfoText.Font.Bold = True
InfoText.Text = "Page: "
'Ad the new Label as the final step in the process
'else you will have to take the new control in the Enumerator
'into account. Too much work, just do it at the end!
'Insert the Label control as the first control of the Pager.
Pager.Controls.AddAt(0, InfoText)
End If
End Sub
Page_Load
事件负责通过查询字符串中的 page
参数捕获传递给表单的页码。现在,您可以让 DataGrid
进行数据分页,或者您可以自定义数据库查询字符串以限制返回的结果,使其仅包含必要的记录。
如果使用 MySQL 作为数据引擎,可以使用 LIMIT
函数来限制返回的记录数。例如,"SELECT * FROM SampleTable WHERE SampleField like ='sampleQuery%' LIMIT " & intP * 25 & ", 25"
。如果使用类似的查询,您将只收到从 intP * 25
开始的 25 条记录。因此,您可以限制返回的数据量并加快页面速度。
Page_Load 事件
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'The value of the page number will be stored in intP
Dim intP as Integer
'Get the value of the QueryString for the "page" parameter
If Not Request.QueryString.Item("page") Is Nothing Then
intP = Request.QueryString.Item("page").ToString.Trim
'If using custom paging, create a data connection and
'pass it the value of intP
'and do the paging in the database query. In MySQL,
'use the LIMIT function to restrict the number of records returned.
'If not using custom paging, just continue as usual
'and let the Datagrid select the relevant records to display.
CustomGrid.DataSource = YourDataSet
'Bind the Datagrid to the new Datatable/Dataset
CustomGrid.DataBind()
'Set the CurrentPageIndex of the Datagrid manually
CustomGrid.CurrentPageIndex = intP
End Sub
由于分页现在是手动处理的,因此您可以禁用 DataGrid
的 Viewstate。嗯,这是如果您只使用 Viewstate 来分页 DataGrid
。如果您需要能够编辑网格,那么您仍然需要启用 Viewstate。
通过实现自定义分页,您可以实现三个目标:
- 禁用
DataGrid
的 Viewstate,从而节省带宽。 - 让搜索引擎索引更多页面。
- 使用自定义 SQL 查询实现自定义分页,从而减少分页查询所需的数据库时间。
关注点
我讨厌在编码时使用 Goto
函数,但这是我第一次别无选择而不得不使用 Goto
。分页器文档不充分,我只能根据有限的知识来做。当对枚举器进行更改时,您必须重新加载枚举器,因此从枚举器的开头开始,因此使用了 Goto
。
本文基于 Munsifali Rashid 和 Razi Bin Rais 关于自定义 DataGrid 分页的文章。
工作示例
本文源于一种需求,我必须找到一种方法来限制数据库连接时间并让更多页面被索引。您可以在 SearchForMore.Info 的 搜索页面 上看到代码的工作示例,当您进行搜索时。查看 DataGrid 底部分页器中的链接。