您的位置:首页技术开发.Net 专栏 → ASP.NET如何创建搜索引擎友好的 URL?

ASP.NET如何创建搜索引擎友好的 URL?

时间:2010/1/21 10:38:00来源:本站整理作者:我要评论(0)

ASP.NET 3.5 SP1中提供了一种路由技术。ASP.NET 路由是一种能够使我们在ASP.NET应用程序中利用一种可描述的、对搜索引擎和用户很友好的URL访问资源的技术。这种URL不必物理地映射到真正的资源。比如:
http://dotnet.aspx.cc/Article.aspx?articleId=8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8
这个 URL 实际上是映射到网站根目录下的一个Article.aspx文件。使用ASP.NET路由技术,可以使用类似下面的URL进行访问:
http://dotnet.aspx.cc/article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/read.aspx

实现这种URL,有两种技术可以做到:URL重写和 URL路由:
1,URL 重写通过在将请求发送到网页之前实际更改 URL 来处理传入请求。例如,一个使用 URL 重写的应用程序可能会将 URL 从 /article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/read.aspx 更改为 /Article.aspx?articleId=8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8。此外,URL 重写通常没有相应的 API 来创建基于模式的 URL。在 URL 重写中,如果更改了 URL 模式,则必须手动更新包含原始 URL 的所有超链接。
2,由于 ASP.NET 路由可以从 URL 提取值,所以处理传入请求时不更改 URL。如果必须创建一个 URL,则将参数值传递到为您生成 URL 的方法中。若要更改 URL 模式,请在某位置更改该模式,您在应用程序中创建的基于该模式的所有链接将自动使用新模式。

若要启用路由,必须更改应用程序的配置文件来注册路由程序集,并添加 UrlRoutingModule 类作为模块。还必须为路由创建一个自定义路由处理程序。该处理程序实现IRouteHandler 接口并创建 Web 窗体(.aspx 文件)的一个实例,该实例将为请求的实际终结点。

下面我们就以完整的例子来简单说明如何在网站发布系统中使用这项技术。

1,首先创建表 Article 用来存储文章数据内容,从 SQL Server 2000 创建脚本功能创建出SQL语句:

SQL 代码
CREATETABLE[Article](
    
[ArticleId][int]IDENTITY(1,1)NOTNULL,
    
[Title][nvarchar](255) COLLATE Chinese_PRC_CI_ASNOTNULL,
    
[CreateDate][datetime]NOTNULLCONSTRAINT[DF_Article_CreateDate]DEFAULT(getdate()),
    
[Content][ntext]COLLATE Chinese_PRC_CI_ASNOTNULL,
    
CONSTRAINT[PK_Article]PRIMARYKEY  CLUSTERED
    (
        
[ArticleId]
    )  
ON[PRIMARY]
)
ON[PRIMARY]TEXTIMAGE_ON[PRIMARY]
GO


2,在VS2008SP1或者VS2010中,新建一个ASP.NET网站,添加对System.Web.Routing的引用;
 

3,创建自定义路由处理程序,在网站工程中添加新项“类”,命名为ArticleRouteHandler.cs,类的网站内容如下:

C# 代码
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;

usingSystem.Web.UI;
usingSystem.Web.Routing;
usingSystem.Web.Compilation;

///<summary>
///ArticleRouteHandler 的摘要说明
///</summary>
publicclassArticleRouteHandler : IRouteHandler
{
  
publicArticleRouteHandler()
  {
    
//
    
//TODO: 在此处添加构造函数逻辑
    
//
  }

  
publicIHttpHandler GetHttpHandler(RequestContext requestContext)
  {
    
stringArticleGuid=requestContext.RouteData.Values["ArticleGuid"]asstring;
    HttpContext context
=HttpContext.Current;
    context.Items.Add(
"ArticleGuid", ArticleGuid);
    
stringaction=(requestContext.RouteData.Values["Action"]asstring).ToLower();
    
if(action.Equals("read"))
      
returnBuildManager.CreateInstanceFromVirtualPath("~/ArticleShow.aspx",typeof(Page))asPage;
    
elseif(action.Equals("new"))
      
returnBuildManager.CreateInstanceFromVirtualPath("~/ArticleAdd.aspx",typeof(Page))asPage;
    
elseif(action.Equals("edit"))
      
returnBuildManager.CreateInstanceFromVirtualPath("~/ArticleEdit.aspx",typeof(Page))asPage;
    
elseif(action.Equals("comment"))
      
returnBuildManager.CreateInstanceFromVirtualPath("~/ArticleComment.aspx",typeof(Page))asPage;
    
elseif(action.Equals("print"))
      
returnBuildManager.CreateInstanceFromVirtualPath("~/ArticlePrint.aspx",typeof(Page))asPage;
    
else
      
returnBuildManager.CreateInstanceFromVirtualPath("~/ArticleList.aspx",typeof(Page))asPage;
  }
}

注意:

using System.Web.UI;
using System.Web.Routing;
using System.Web.Compilation;

这3行代码是新加的。 

在这里,我们将URL地址中的占位符参数放到 HttpContext.Current 对象中,以便在真正的处理页面中进行获取,然后执行相应的操作。关键的代码是这几句:

string ArticleGuid = requestContext.RouteData.Values["ArticleGuid"] as string;
HttpContext context = HttpContext.Current;
context.Items.Add("ArticleGuid", ArticleGuid);

4,在Global里注册路由,其代码为:

C# 代码
<%@ Application Language="C#"%>
<%@ Import Namespace="System.Web.Routing"%>

<script. RunAt="server">

  
voidApplication_Start(objectsender, EventArgs e)
  {
    RegisterRoutes(RouteTable.Routes);
  }

  
publicstaticvoidRegisterRoutes(RouteCollection routes)
  {
    routes.Add(
"ArticleRoute",newRoute
    (
      
"Article/{ArticleGuid}/{Action}.aspx",
            
newArticleRouteHandler()
    )
    );
  }
    
</script>

这里,作为例子,只定义了一条URL规则,Article/{ArticleGuid}/{Action}.aspx。 

5,按照自定义路由处理程序中定义的实际处理程序,分别添加ArticleShow.aspx、ArticleAdd.aspx、ArticleEdit.aspx、ArticleComment.aspx、ArticlePrint.aspx和ArticleList.aspx等真正的处理程序。作为例子,这里列出ArticleShow.aspx、ArticleAdd.aspx和ArticleList.aspx的源代码分别如下:

ArticleAdd.aspx

ASPX 代码
<%@ Page Language="C#"ValidateRequest="false"%>

<%@ Import Namespace="System.Data"%>
<%@ Import Namespace="System.Data.SqlClient"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script.runat="server">

  protected
voidButton1_Click(object sender, EventArgs e)
  {
    String ConnectionString
="Data Source=(local);Initial Catalog=ArticleDev;User ID=sa;Password=sa";
    SqlConnection cn
=newSqlConnection(ConnectionString);
    cn.Open();
    String sql
="Insert Into Article(Title,Content) Values(@Title,@Content)";
    SqlCommand cmd
=newSqlCommand(sql, cn);
    cmd.Parameters.AddWithValue(
"@Title", TextBox1.Text);
    cmd.Parameters.AddWithValue(
"@Content", TextBox2.Text);
    
intret=cmd.ExecuteNonQuery();
    
if(ret==1)
    {
      Label1.Text
="添加成功。";
    }
    
else
    {
      Label1.Text
="添加失败。";
    }
    cn.Dispose();

  }
</script>

<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
  
<title></title>
</head>
<body>
  
<form.id="form1"runat="server">
  
<div>文章标题:<asp:TextBoxID="TextBox1"runat="server"Width="767px"></asp:TextBox></div>
  
<div>文章内容:<br/>
    
<asp:TextBoxID="TextBox2"runat="server"Width="845px"Height="319px"TextMode="MultiLine">
    
</asp:TextBox></div>
  
<asp:ButtonID="Button1"runat="server"Text="添加文章"OnClick="Button1_Click"/>
  
<asp:LabelID="Label1"runat="server"Text=""></asp:Label>
  
</form>
</body>
</html>

ArticleShow.aspx

ASPX 代码
<%@ Page Language="C#"%>
<%@ Import Namespace="System.Data"%>
<%@ Import Namespace="System.Data.SqlClient"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script.runat="server">

  protected
voidPage_Load(object sender, EventArgs e)
  {
    
intArticleGuid=0;
    HttpContext context
=HttpContext.Current;
    
if(context.Items["ArticleGuid"]!=null)
    {
      Int32.TryParse(context.Items[
"ArticleGuid"].ToString(), out ArticleGuid);
    }
    
if(ArticleGuid<1)
    {
      ArticleTitle.InnerHtml
="加载文章错误";
      ArticleContent.InnerHtml
="指定的 标识 无效!";
      ArticleContent.Style[
"color"]="#f00";
    }
    
else
    {
      String ConnectionString
="Data Source=(local);Initial Catalog=ArticleDev;User ID=sa;Password=sa";
      SqlConnection cn
=newSqlConnection(ConnectionString);
      cn.Open();
      String sql
="Select * From Article Where ArticleId = @ArticleId";
      SqlCommand cmd
=newSqlCommand(sql, cn);
      cmd.Parameters.AddWithValue(
"@ArticleId", ArticleGuid);
      SqlDataReader dr
=cmd.ExecuteReader();
      
if(dr.Read())
      {
        ArticleTitle.InnerHtml
=dr["Title"].ToString();
        ArticleContent.InnerHtml
=dr["Content"].ToString();
      }
      
else
      {
        ArticleTitle.InnerHtml
="加载文章错误";
        ArticleContent.InnerHtml
="指定的文章不存在!";
        ArticleContent.Style[
"color"]="#f00";
      }
      cn.Dispose();
    }    
  }
</script>

<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
  
<title></title>
</head>
<body>
  
<form.id="form1"runat="server">
  
<h2id="ArticleTitle"runat="server"style="text-align:center">
  
</h2>
  
<hr/>
  
<divid="ArticleContent"runat="server">
  
</div>
  
</form>
</body>
</html>

这段代码中,我们从自定义路由处理程序中添加的 HttpContext 对象中取出参数 context.Items["ArticleGuid"],然后进行处理。

ArticleList.aspx

ASPX 代码
<%@ Page Language="C#"%>
<%@ Import Namespace="System.Data"%>
<%@ Import Namespace="System.Data.SqlClient"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script.runat="server">

  protected
voidPage_Load(object sender, EventArgs e)
  {
    String ConnectionString
="Data Source=(local);Initial Catalog=ArticleDev;User ID=sa;Password=sa";
    SqlConnection cn
=newSqlConnection(ConnectionString);
    cn.Open();
    String sql
="Select * From Article Order By ArticleId DESC";
    SqlCommand cmd
=newSqlCommand(sql, cn);
    SqlDataReader dr
=cmd.ExecuteReader();
    GridView1.DataSource
=dr;
    GridView1.DataBind();
    cn.Dispose();
  }
</script>

<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
    
<title></title>
</head>
<body>
    
<form.id="form1"runat="server">
    
<asp:GridViewID="GridView1"runat="server"AutoGenerateColumns="false">
    
<Columns>
    
<asp:HyperLinkFieldDataNavigateUrlFields="ArticleId"DataTextField="Title"
      DataNavigateUrlFormatString
="~/Article/{0}/read.aspx"HeaderText="标题"/>
    
<asp:BoundFieldDataField="CreateDate"HtmlEncode="false"HeaderText="发布日期"
     DataFormatString
="{0:yyyy-MM-dd HH:mm:ss}"/>
    
</Columns>    
    
</asp:GridView>
    
</form>
</body>
</html>

6,如果IIS里设置的ASP.NET版本是 ASP.NET 4.0,无需配置以下的配置,如果是ASP.NET 2.0,则需要在web.config里配置路由。在应用程序的 Web.config 文件中,将 ASP.NET 路由程序集添加到 assemblies 元素

XML/XHTML 代码
<assemblies>
  
<addassembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>

如果应用程序在 IIS 6.0 或 IIS 7.0 经典模型下运行,则将 UrlRoutingModule 类添加到 httpModules 元素

XML/XHTML 代码
<httpModules>
  
<addname="UrlRoutingModule"
   type
="System.Web.Routing.UrlRoutingModule,
         System.Web.Routing,
         Version=3.5.0.0,
         Culture=neutral,
         PublicKeyToken=31BF3856AD364E35"
/>
</httpModules>

 下面就可以使用下面的地址进行访问了。当然,这里只是一个例子,更多的功能处理有待于我们在实践中加以处理。
 

相关视频

    没有数据

相关阅读 ie6下面asp.net mvc3 部署应用程序在asp.net mvc中实现右键菜单和简单的分页教程ASP.NET中MVC框架模式方法如何实现分享ASP.NET 2.0 中保护机密数据ASP.NET配置文件Web.configASP.NET 2.0 AJAX中Webservice调用方法ASP.NET 的安全认证实现ASP.NET生成随机密码功能

文章评论
发表评论

热门文章 没有查询到任何记录。

最新文章 什么是.NET中的TDD?ASP.NET AJAX入门简介 WebMatrix入门教程VC++2008中如何调用GetOpenFileName打开文件PlaySound函数在VC++6.0中如何播放音乐及声请问VC++回调函数怎么用

人气排行 嵌入式实时操作系统VxWorks入门教程ArrayList 与 string、string[] 的转换C#遍历整个文件夹及子目录的文件代码WebMatrix入门教程asp.net判断文件或文件夹是否存在c#判断数据NULL值的方法vc++6.0怎么写Windows简单窗口代码.net解决数据导出excel时的格式问题