[翻译]在asp.net 2.0中结合母板页使用meta标签(扩展@Page指令)

原文地址:http://www.codeproject.com/KB/aspnet/PageTags.aspx
[原文原码下载(C#)]
[原文原码下载(VB)]


在asp.net 2.0中结合母板页使用meta标签(扩展@Page指令)


原文发布日期:2007.02.02
作者:Jim Azar
翻译:webabcd


介绍
母板页是asp.net 2.0中的一个非常强大的特性,但是它却不能提供一个实现最基础的针对搜索引擎优化的方法。如果你想你的web页被搜索引擎收录并提高排名,那么你就需要在每一个页都指定一个title和meta标记。本文将说明如何扩展你的asp.net页,以使得在使用母板页的时候你可以直接在你内容页的@Page指令中指定你的meta标签的描述和meta标签的关键字。


背景
当你要针对搜索引擎优化你的web页的时候,设置页的title标签和页的meta描述是其中最重要的因素之一。<title>和meta标签实际上是在每个页的HTML的<head>部分,下面出示一个Rhinoback online backup的例子。
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>
   Rhinoback Professional Secure Online Backup Services for Small and Medium Business - SMB
</title>
<meta name="description" content="Professional Online Backup Services. 
      Rhinoback provides robust backup functionality at affordable prices.  
      Premium features, premium services, low prices.  Get the most for 
      your money with Rhinoback!"
 />
<meta name="keywords" content="backup, online backup, secure backup, cheap backup, 
      free backup, offsite backup,internet backup, secure files, offsite data storage, 
      privacy, security, features, low prices, premium service, remote backup"
 />
</head>
<body>
     
<!-- page content -->
</body>
</html>

<title>标签的文本显示在浏览器的顶端。从下面的例子中可以看到<title>在IE中的显示


当你的页被搜索引擎收录的时候,meta描述的文本则在搜索引擎的列表中显示。下面的例子来自google。带下划线的标题的下面的文本就来自页的meta描述标签。如果没有meta描述标签,那你的页在搜索引擎的列表中将显示为你的页上的某一处的文本。指定你的每一个页的描述文本要比把这些事情交给搜索引擎做好的多。

母板页已经被证明是asp.net 2.0中非常有用的一个特性。本文不是来说明母板页的细节或是如何实现它,因为这样的文章太多了。当我们在母板页中使用了<head>的话,那么母板页下的所有内容页都将自动的包括这个<head>。幸运的是开发人员可以在内容页中直接在@Page指令中修改title属性来修改内容页的title。
<%@ Page Language="C#" MasterPageFile="~/PageTags.master" AutoEventWireup="true" CodeFile="home.aspx.cs" Inherits="home" Title="My home page title" %>

上面的@Page指令说明了这是一个使用了母板页的内容页。如果你要指定meta标签的话,应该在内容页中指定。你可以看到@Page指令中有一个“Description”属性,但是它不能在你的页上创建meta描述标签。事实上,即使你指定了“Description”属性,最后也会被忽略掉而不做任何事的。

我不可能让站点的所有页都使用同一个描述,而且我想给每一页都加一个关键字。我们首先想到的解决办法就是在后置代码中插入我们想要的meta标签到每一个页的<head>里,就像如下的做法
C#
protected void Page_Load(object sender, EventArgs e)
{
    HtmlMeta tag 
= new HtmlMeta();
    tag.Name 
= "description";
    tag.Content 
= "My description for this page";
    Header.Controls.Add(tag);
}

VB
Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs)
    
Dim tag As HtmlMeta = New HtmlMeta()
    tag.Name 
= "description"
    tag.Content 
= "My description for this page"
    Header.Controls.Add(tag)
End Sub

这种解决方法有一个问题,就是页的标题,meta描述,meta关键字都是相互关联的,所以我们想的是最好让标题和描述在同一个文件中指定。在Page_Load方法里确实可以很简单的在.aspx页中加入一个<script>标签,但是我想要一个更简单的设置和检查每一页标签的解决方案。

在接下来的方案中我们会看到如何通过扩展@Page指令给每一页加上meta标签。


解决方案
我创建了一个继承自System.Web.UI.Page的page基类,并且让我的内容页继承自我的BasePage类。BasePage类包含了在.aspx页中给header控件中增加meta标签的代码,当我们继承了BasePage的之后,这段代码就只需要在一个地方存在,而不用每一页都写一遍。
C#
using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;

/// <SUMMARY>
/// 为了给内容页增加meta标签而扩展基类
/// </SUMMARY>

public class BasePage : Page
{
    
private string _keywords;
    
private string _description;
    
// 构造函数
    
// 增加一个Init的事件处理
    public BasePage()
    
{
        Init 
+= new EventHandler(BasePage_Init);
    }


    
// 页将使用这个基类初始化
    
// 如果可用则增加meta关键字和meta描述
    void BasePage_Init(object sender, EventArgs e)
    
{

        
if (!String.IsNullOrEmpty(Meta_Keywords))
        
{
            HtmlMeta tag 
= new HtmlMeta();
            tag.Name 
= "keywords";
            tag.Content 
= Meta_Keywords;
            Header.Controls.Add(tag);
        }


        
if (!String.IsNullOrEmpty(Meta_Description))
        
{
            HtmlMeta tag 
= new HtmlMeta();
            tag.Name 
= "description";
            tag.Content 
= Meta_Description;
            Header.Controls.Add(tag);
        }

    }


    
/// <SUMMARY>
    
/// 获取或设置页的meta关键字
    
/// </SUMMARY>

    public string Meta_Keywords
    
{
        
get 
        

            
return _keywords; 
        }

        
set 
        

            
// 删掉多余的空格
            
// 译者注:\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]。
            _keywords = Regex.Replace(value, "\\s+"" "); 
        }

    }


    
/// <SUMMARY>
    
/// 获取或设置页的meta描述
    
/// </SUMMARY>

    public string Meta_Description
    
{
        
get 
        

            
return _description; 
        }

        
set 
        
{
            
// 删掉多余的空格
            
// 译者注:\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]。
            _description = Regex.Replace(value, "\\s+"" "); 
        }

    }

}

VB
Imports System
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Text.RegularExpressions


' 为了给内容页增加meta标签而扩展基类

Public Class BasePage
    
Inherits Page

    
Dim _keywords As String
    
Dim _description As String
    
' 页将使用这个基类初始化
    ' 增加一个Init的事件处理
    Public Sub New()
        
AddHandler Init, New EventHandler(AddressOf BasePage_Init)
    
End Sub


    
' 页将使用这个基类初始化
    ' 如果可用则增加meta关键字和meta描述
    Sub BasePage_Init(ByVal sender As ObjectByVal e As EventArgs)

        
If Not String.IsNullOrEmpty(Meta_Keywords) Then
            
Dim tag As HtmlMeta = New HtmlMeta()
            tag.Name 
= "keywords"
            tag.Content 
= Meta_Keywords
            Header.Controls.Add(tag)
        
End If

        
If Not String.IsNullOrEmpty(Meta_Description) Then
            
Dim tag As HtmlMeta = New HtmlMeta()
            tag.Name 
= "description"
            tag.Content 
= Meta_Description
            Header.Controls.Add(tag)
        
End If
    
End Sub



    
'获取或设置页的meta关键字
    Public Property Meta_Keywords() As String
        
Get
            
Return _keywords
        
End Get
        
set 
            
' 删掉多余的空格
            ' 译者注:\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]。
            _keywords = Regex.Replace(value, "\\s+"" ")
        
End Set
    
End Property



    
' 获取或设置页的meta描述
    Public Property Meta_Description() As String
        
Get
            
Return _description
        
End Get
        
Set(ByVal value As String)
            
' 删掉多余的空格
            ' 译者注:\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]。
            _description = Regex.Replace(value, "\\s+"" ")
        
End Set
    
End Property

End Class

Meta_Keywords属性和Meta_Description属性是公共的,你可以在类实例化后设置它们。当某个类继承自这个类并被初始化后,Base_Init将被调用并在页中增加meta标签

C#
public partial class home : BasePage 
{
    
protected void Page_Load(object sender, EventArgs e)
    
{

    }

}

VB
Partial Class home
    
Inherits BasePage
    
Sub Page_Load(ByVal sender As ObjectByVal e As EventArgs)
    
    
End Sub

End Class

注意每一个继承自BasePage的页都可以通过属性或代码来插入meta标签。现在我们可以直接在.aspx文件的@Page指令中指定Meta_Keywords属性和Meta_Description属性的值。示例如下
<%@ Page Language="C#" MasterPageFile="~/PageTags.master" AutoEventWireup="true" CodeFile="home.aspx.cs" Inherits="home"  
    CodeFileBaseClass
="BasePage" 
    Title
="My home page title" 
    Meta_Keywords
="page directive, extension, dotnet, asp.net"
    Meta_Description
="This is the meta description for my home page."                          
%>

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    
<h3>My home page content<h3>
    
<p>
    This is the content on my home page.  This page has an appropriate title tag and
    also has meta tags for keywords and description that are relative to this page.
    The title tag is essential to good search engine optimization and the meta
    description is the text that the search engine will display when your 
    page is listed in search results.  The title and meta description should be
    set specific to each page and should describe the content of the page. 
    
</p>
</asp:Content>

注意这里增加了一个CodeFileBaseClass属性,这是必需的,它可以引用BasePage类的公共属性


重点提要
你应该注意到了,在BasePage类里使用了正则表达式。这是因为在你的.aspx里添加描述和关键字的时候可能会是多行,就像下面这个例子似的
<%@ Page Language="C#" MasterPageFile="~/IdeaScope.master" AutoEventWireup="true" 
  CodeFile
="is.aspx.cs" Inherits="_is"
  CodeFileBaseClass
="BasePage" 
  
  Title
="Effective Customer Feedback Management, Improve Customer Commmunication" 
  
  Meta_Keywords
="Customer Feedback, Customer Opinion, feedback, opinion,
       idea, ideas, idea management, customer feedback management,         
        product management, product manager, product marketing,         
        product marketing manager
"
                              
  Meta_Description
="IdeaScope is an on-demand and embedded solution that allows 
       you to capture, prioritize and centrally manage customer feedback. Make your
       customer feedback process more efficient. Save 
time and involve more 
       stakeholders without significant cost.
"                          
%>

如果不用正则表达式转换它们的话,这些标记就会包含很多的新行和空格,这会使一些搜索引擎不知所措,所以我们要让这些标记方便搜索引擎的收录。

还有另外一个问题就是,Visual Studio 2005不认识Meta_Keywords属性和Meta_Description属性。你如果在@Page指令中指定了这两个属性的话,将会看到这些属性的下面会出现红色的波浪线,VS2005会认为它们是无效的,但实际上它仍然可以正确的编译和运行。如果你不想看到这些错误的话,你可以在Visual Studio的schema里给@Page指令增加如下代码。
<xsd:attribute name="Meta_Keywords" vs:nonfilterable="true" />
<xsd:attribute name="Meta_Description" vs:nonfilterable="true" />

这些节点应该作为<xsd:complexType name="PageDef">的子节点被插入,如果你把Visual Studio 2005安装在默认路径,那么这个schema文件的路径则是

C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\schemas\html\page_directives.xsd

本文示范了如何通过扩展@Page指令使其支持meta关键字和meta描述。你也可以使用相同的方法增加其他的meta标签。原码文件和示例项目包括了c#和vb两种语言。感谢Scott Guthrie的博客文章,Obsure but cool feature in ASP.NET 2.0一文为本解决方案提供了技术支持。


你的评论和建议将会证明本文是受欢迎的
posted @ 2007-02-09 09:13  webabcd  阅读(8055)  评论(8编辑  收藏  举报