65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET Google 网站地图提供程序

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.40/5 (4投票s)

2006 年 10 月 10 日

CPOL

9分钟阅读

viewsIcon

96991

downloadIcon

2729

使用 ASP.NET Provider 模型生成动态 Google 网站地图。

Sample Image - GoogleSiteMapProvider.jpg

引言

Google 网站地图是网站开发人员、网站管理员以及几乎所有拥有网站的人的重要工具。如果您不知道 Google 网站地图是什么,请访问 http://www.google.com/webmasters。Google 网站地图是一个 XML 文件,它指示 Google 爬虫在您的网站上应访问哪些 URL,并允许您告诉爬虫页面更新的频率,还可以为网站内的页面设置相对优先级。Google 提供的说明是手动编写 XML 文件,但当然,对于动态网站,您不希望这样做。

您需要的是一个动态的 Google 网站地图生成器,它可以提供关于您网站的实时数据。市面上有很多这类工具。我遇到的具体问题是我有一些有特定需求的网站,但 90% 的需求是完全相同的。因此,我决定利用 Provider 模型,开发一个用于提供网站地图的基础提供程序,然后可以为后续网站出现的每种特定情况扩展新的提供程序。由于我之前没有做过任何关于 Google 网站地图或 Provider 的工作,这也提供了一个很好的学习机会。

Google 网站地图是什么样的?

Google 网站地图只是一个 XML 文件,告诉 Google 爬虫在网站上要查找哪些 URL。

对于网站中要索引的每个 URL,XML 文件中都应该有一个 <url> 条目。每个文件最多可以包含 10,000 个 URL,但可以为网站提交多个网站地图。lastMod 属性告诉 Google 页面最后修改的时间,changefreq 属性告诉 Google 页面更改的频率,而 priority 是页面相对于您网站中所有其他页面的相对度量。正如 Google 清楚解释的那样,您无法通过网站地图来提高网站排名,它们只是帮助 Google 爬取您希望它爬取的所有网站部分的工具。从这个意义上说,它有点像一个超级 robots.txt 文件。

背景

我过去曾使用过 ASP.NET Provider 模型,但我从未真正为任何东西开发过自己的自定义提供程序。我利用了 MSDN 资源并下载了一个自定义提供程序的源代码。我甚至阅读了说明!

Provider 模型允许在不重新编译的情况下插入不同的代码来完成相同的工作。在应用程序中更改特定任务的提供程序是在web/app config 文件中完成的。配置文件在运行时告诉应用程序执行特定任务的代码。

Providers 最常见的用途是数据提供程序领域 - 一个例子是允许通过在web/app.config 文件中切换提供程序来快速在 SQL Server 提供程序和 Oracle 提供程序之间进行更改。

Google 网站地图提供程序在 web.config 文件中的相关条目如下所示:

<googlesitemaps defaultProvider="BaseGoogleSiteMapProvider">
  <providers>
    <add name="BaseGoogleSiteMapProvider" 
             type="GoogleSiteMap.GoogleSiteMapProvider" />
    <add name="SpecialisedGoogleSiteMapProvider" 
             type="Specialised.GoogleSiteMapProvider" />
  </providers>
</googlesitemaps>

此示例展示了两个提供程序的用法:默认提供程序,以及在必要时使用的专用提供程序。(Specialised.GoogleSiteMapProvider 不在演示项目中,我在此仅作为示例展示。)

要求

我为自己的项目生成的要求是:

  • 能够立即与大多数 ASP.NET 应用程序一起使用。
  • 提供一个完整的“二进制”解决方案 - 无需集成代码或编译 - 只需放入一个二进制文件,修改web.config,然后即可使用。
  • 可扩展,以便更复杂的 ASP.NET 应用程序可以无限制地重新定义提供程序。

解决方案

解决方案是拥有一个包含三个主要类型的单个程序集:

  1. 一个 HTTP Handler,它将在请求时返回 XML(名为 GoogleSiteMapHandler
  2. 一个 Provider 类型(名为 GoogleSiteMapProvider
  3. 一个 Controller 类,用于将 Handler 和 Provider 结合在一起

为什么选择这样做?

实际上,我可以有一个单独的 Handler 文件(.ashx),可以将其放入目标 ASP.NET 网站中。但为了满足要求(1),我希望整个项目都能简单地放入 `\bin` 目录。这就是 Handler 和 Provider 在同一个程序集中的原因。

通过这种方式,我还可以创建继承自基础 Provider、Controller 和 Handler 类的新的程序集,并为使用 HTTP 重定向且 URL 实际上不映射到服务器上物理文件的特定类型的网站创建全新的 Provider。

使用代码

要安装并试用演示项目,只需下载 zip 文件并解压缩。文件 'iFinity.GoogleSiteMapProvider.dll' 应复制到目标网站的 `\bin` 目录中。

然后,打开您的web.config(请记住先备份),然后插入以下行:

在 `<configuration>` 部分下,在 `<configSections>` 下,添加以下条目:

<configuration>
   <configSections>
      <section name="googlesitemaps" 
       type="iFinity.Providers.GoogleSiteMap.GoogleSiteMapSection, 
             iFinity.GoogleSiteMapProvider />                
   </configSections>
</configuration>

请记住,您可能已经有了 `web.config` 中的 `<configuration>` 和 `<configSections>` 条目,但如果没有,请创建它们。

`<configSections>` 中的条目告诉 ASP.NET 在 `app/web.config` 文件中查找名为 'googlesitemaps' 的部分。`type` 属性的格式为 type="typeName, assemblyName",它告诉 ASP.NET 在 'iFinity.GoogleSiteMapProvider' 程序集中有一个名为 'GoogleSiteMapSection' 的类型。`GoogleSiteMapSection` 类型派生自 `System.Configuration.ConfigurationSection`,并提供了运行时类型来表示配置文件中的 Providers 部分。这一切都由 `ProviderBase` 类在运行时完成。

在 `web.config` 文件中要做的下一个条目是实际的 'googlesitemaps' 部分,该部分在 `<configSection>` 条目中已命名。这应该在 `</system.web>` 部分的闭合标签之后,但在 `</config>` 部分的末尾之前完成。

<googlesitemaps defaultProvider="BaseGoogleSiteMapProvider">
  <providers>
     <add name="BaseGoogleSiteMapProvider" 
          type="iFinity.Providers.GoogleSiteMap.GoogleSiteMapProvider" 
          defaultPagePriority="0.5" defaultPageUpdateFrequency="daily" 
          sitePageTypes="aspx,html,htm" />
  </providers>
</googlesitemaps>

此条目告诉 ASP.NET 在运行时可以使用哪些提供程序。如果使用默认提供程序以外的任何内容,调用代码将需要修改才能做到这一点。但是,要更改要使用的默认提供程序,只需将 `defaultProvider` 属性与列表中的提供程序名称匹配即可。

对 `web.config` 要做的最后更改是添加 HTTP Handler 以实际生成 Sitemap。这在 `web.config` 的 `system.web` 部分下的 `httpHandlers` 部分中完成。

<httpHandlers>
   <add verb="*" path="GoogleSiteMapHandler.axd" 
        type="iFinity.Providers.GoogleSiteMap.GoogleSiteMapHandler,
              iFinity.GoogleSiteMapProvider"/>
</httpHandlers>

此条目指示任何对 'GoogleSiteMapHandler.axd' 的请求都会加载 iFinity.GoogleSiteMapProvider 程序集并调用 'iFinity.Providers.GoogleSiteMap.GoogleSiteMapHandler' 类型。只要指定的类型实现了 `IHttpHandler` 接口(此类型确实实现了),ASP.NET 就会自动为您完成此操作。

请注意,Handler 不需要包含在 Provider 中,并且在某种程度上,将 Handler 类型包含在 Provider 模型中会略微“污染”它。按理说,Handler 应该调用 ASP.NET `ProvidersHelper` 命名空间,以便为它提供正确的配置 Provider。为了完全正确,Handler 类型和 `GoogleSiteMapService` 类型应该放在单独的命名空间和程序集中。但由于我打算以后为 Provider 创建单独的程序集,所以我乐于接受我的模型。其他人可能会声称这是不正确的,并且他们有充分的理由。

程序流程

当对 GoogleSiteMapHandler.axd 发出 HTTP 请求时(无论是来自 Google 爬虫,还是在浏览器中键入 'yoursite.com/googleSiteMapHandler.axd'),ASP.NET 会加载 `httpHandlers` web.config 部分中命名的类型/程序集。在此实例中,它与 Provider 是同一个 DLL,尽管如前所述,它不必是。

ASP.NET 会读取 Provider,并实例化在 `googlesitemaps` 配置部分中命名的默认 Provider 类型的对象。然后,这个 Provider 对象会被要求提供构成网站地图的 XML。由于程序集还包含默认提供程序的基本实现,因此会调用此提供程序。演示项目中的基础实现只是迭代目录并读取 `sitePageTypes` 属性中所有匹配命名扩展名的文件。然后,此 XML 会通过调用堆栈向上返回,并通过 `HTTPHandler` 作为 XML 返回,最终将 XML 输出到浏览器或 Google 爬虫。

扩展可能性

如前所述,此项目旨在增进对 Provider 模型的理解,并提供一个可以扩展以更好地处理更复杂的 ASP.NET 应用程序模型的基础实现。

要扩展此代码,有两种可能的方向。第一种也是最简单的一种,就是修改 `GoogleSiteMapProvider IteratePages()` 过程中的代码。可以修改它以更好地为特定网站提供网站地图 - 在这方面可能性非常开放。

第二种,在概念上更好但稍显复杂,是简单地引用提供的程序集,并通过继承 `GoogleSiteMapProvider` 类型来创建自己的 Provider。您需要重新定义派生类中的 `IteratePages()` 以更好地索引网站中的页面,但其他所有内容都可以保持不变。新 Provider 将被编译成一个单独的程序集,然后在 `googlesitemaps` 配置部分中命名为默认 Provider。

例如,假设您创建了一个名为 'MyNewGoogleSiteMapProviderType' 的新 Provider 类,并将其编译到一个名为 'MyNewGoogleSiteMapProviderAssembly.dll' 的程序集中。配置条目将是:

<add name="BaseGoogleSiteMapProvider" type="MyNewGoogleSiteMapProviderType, 
           MyNewGoogleSiteMapProviderAssembly" 
     defaultPagePriority="0.5" defaultPageUpdateFrequency="daily"/>

这将意味着您的新类型将被调用以提供网站的页面列表。基础 Provider 将负责将其格式化为 Sitemap 格式并输出 XML。您可以将所有其他 web.config 条目保持不变 - 内置的 HttpHandler 将负责调用您的 Provider 来获取您网站的页面列表。您如何提供该列表由您决定!

下一步

我将开发 Provider 模型的新实现以适应 DotNetNuke,因为这是我进行大量开发的一款平台。DotNetNuke 使用 `HttpRedirection` 方法从单个 default.aspx 页面提供许多 URL,因此无法用于从物理文件生成 Sitemap。

然后,我将为 DotNetNuke 网站中使用的每种不同的专用模块创建不同的 Provider。一些模块为单个 URL 提供各种不同的内容,具体取决于数据库驱动的内容。通过传统的 Google 索引,许多内容可能无法被正确找到和索引。

请注意,此页面中的 XML 示例中为了适应页面宽度而放置了分页符,您的 web.config 文件中不需要这样做。

版权声明

您可以使用、修改和扩展提供的代码,前提是您不删除源代码中的版权信息,也不试图将代码或本文冒充为自己的。当然,免费的演示代码没有工作的保证,并且提供的下载中可能存在错误。

如果您使用此代码并发现它有用,我将很感激您链接回我的网站:http://www.ifinity.com.au/

© . All rights reserved.