注意:本文所讲述的并非MVC框架。
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
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->CREATE TABLE
[Article]
(
[ArticleId]
[int]
IDENTITY (1, 1) NOT
NULL ,
[Title]
[nvarchar]
(255) COLLATE Chinese_PRC_CI_AS NOT
NULL ,
[CreateDate]
[datetime]
NOT NULL
CONSTRAINT [DF_Article_CreateDate]
DEFAULT (getdate()),
[Content]
[ntext] COLLATE
Chinese_PRC_CI_AS NOT NULL
,
CONSTRAINT [PK_Article]
PRIMARY KEY CLUSTERED
(
[ArticleId]
) ON
[PRIMARY]
)
ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO
2,在VS2008SP1或者VS2010中,新建一个ASP.NET网站,添加对System.Web.Routing的引用;
3,创建自定义路由处理程序,在网站工程中添加新项“类”,命名为ArticleRouteHandler.cs,类的网站内容如下:
C#
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->using System;
using
System.Collections.Generic;
using
System.Linq;
using System.Web;
using
System.Web.UI;
using System.Web.Routing;
using
System.Web.Compilation;
///
///ArticleRouteHandler 的摘要说明
///
public
class ArticleRouteHandler :
IRouteHandler
{
public
ArticleRouteHandler()
{
//
//TODO:
在此处添加构造函数逻辑
//
}
public
IHttpHandler GetHttpHandler(RequestContext
requestContext)
{
string
ArticleGuid = requestContext.RouteData.Values["ArticleGuid"]
as string;
HttpContext context =
HttpContext.Current;
context.Items.Add("ArticleGuid",
ArticleGuid);
string action =
(requestContext.RouteData.Values["Action"]
as string).ToLower();
if
(action.Equals("read"))
return
BuildManager.CreateInstanceFromVirtualPath("~/ArticleShow.aspx",
typeof(Page)) as
Page;
else if
(action.Equals("new"))
return
BuildManager.CreateInstanceFromVirtualPath("~/ArticleAdd.aspx",
typeof(Page)) as
Page;
else if
(action.Equals("edit"))
return
BuildManager.CreateInstanceFromVirtualPath("~/ArticleEdit.aspx",
typeof(Page)) as
Page;
else if
(action.Equals("comment"))
return
BuildManager.CreateInstanceFromVirtualPath("~/ArticleComment.aspx",
typeof(Page)) as
Page;
else if
(action.Equals("print"))
return
BuildManager.CreateInstanceFromVirtualPath("~/ArticlePrint.aspx",
typeof(Page)) as
Page;
else
return
BuildManager.CreateInstanceFromVirtualPath("~/ArticleList.aspx",
typeof(Page)) as
Page;
}
}
注意:
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#
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><%@ Application Language="C#"
%>
<%@ Import
Namespace="System.Web.Routing"
%>
<script.
RunAt="server">
void
Application_Start(object sender, EventArgs
e)
{
RegisterRoutes(RouteTable.Routes);
}
public
static void
RegisterRoutes(RouteCollection routes)
{
routes.Add("ArticleRoute",
new Route
(
"Article/{ArticleGuid}/{Action}.aspx",
new
ArticleRouteHandler()
)
);
}
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
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><%@ 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
void
Button1_Click(object sender, EventArgs e)
{
String ConnectionString
= "Data
Source=(local);Initial Catalog=ArticleDev;User ID=sa;Password=sa";
SqlConnection
cn = new
SqlConnection(ConnectionString);
cn.Open();
String sql
= "Insert Into
Article(Title,Content) Values(@Title,@Content)";
SqlCommand
cmd = new SqlCommand(sql,
cn);
cmd.Parameters.AddWithValue("@Title",
TextBox1.Text);
cmd.Parameters.AddWithValue("@Content",
TextBox2.Text);
int ret =
cmd.ExecuteNonQuery();
if (ret == 1)
{
Label1.Text
= "添加成功。";
}
else
{
Label1.Text
= "添加失败。";
}
cn.Dispose();
}
script>
<html
xmlns="http://www.w3.org/1999/xhtml">
<head
runat="server">
<title>title>
head>
<body>
<form.
id="form1"
runat="server">
<div>文章标题:<asp:TextBox ID="TextBox1"
runat="server" Width="767px">asp:TextBox>div>
<div>文章内容:<br
/>
<asp:TextBox ID="TextBox2"
runat="server" Width="845px"
Height="319px" TextMode="MultiLine">
asp:TextBox>div>
<asp:Button ID="Button1"
runat="server" Text="添加文章"
OnClick="Button1_Click" />
<asp:Label ID="Label1"
runat="server" Text="">asp:Label>
form>
body>
html>
ArticleShow.aspx
ASPX
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><%@ 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
void Page_Load(object
sender, EventArgs e)
{
int ArticleGuid
= 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 = new
SqlConnection(ConnectionString);
cn.Open();
String sql
= "Select * From
Article Where ArticleId = @ArticleId";
SqlCommand
cmd = new SqlCommand(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>
<html
xmlns="http://www.w3.org/1999/xhtml">
<head
runat="server">
<title>title>
head>
<body>
<form.
id="form1"
runat="server">
<h2
id="ArticleTitle" runat="server"
style="text-align:center">
h2>
<hr
/>
<div
id="ArticleContent" runat="server">
div>
form>
body>
html>
这段代码中,我们从自定义路由处理程序中添加的 HttpContext 对象中取出参数
context.Items["ArticleGuid"],然后进行处理。
ArticleList.aspx
ASPX
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><%@ 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
void Page_Load(object
sender, EventArgs e)
{
String ConnectionString = "Data
Source=(local);Initial Catalog=ArticleDev;User ID=sa;Password=sa";
SqlConnection
cn = new
SqlConnection(ConnectionString);
cn.Open();
String sql
= "Select * From
Article Order By ArticleId DESC";
SqlCommand
cmd = new SqlCommand(sql,
cn);
SqlDataReader dr =
cmd.ExecuteReader();
GridView1.DataSource =
dr;
GridView1.DataBind();
cn.Dispose();
}
script>
<html
xmlns="http://www.w3.org/1999/xhtml">
<head
runat="server">
<title>title>
head>
<body>
<form.
id="form1"
runat="server">
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="ArticleId" DataTextField="Title"
DataNavigateUrlFormatString="~/Article/{0}/read.aspx" HeaderText="标题"
/>
<asp:BoundField DataField="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
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><assemblies>
<add
assembly="System.Web.Routing, Version=3.5.0.0,
Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
assemblies>
如果应用程序在 IIS 6.0 或 IIS 7.0 经典模型下运行,则将 UrlRoutingModule 类添加到 httpModules 元素
XML/XHTML
代码
<!--
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><httpModules>
<add
name="UrlRoutingModule"
type="System.Web.Routing.UrlRoutingModule,
System.Web.Routing,
Version=3.5.0.0,
Culture=neutral,
PublicKeyToken=31BF3856AD364E35"/>
httpModules>
下面就可以使用下面的地址进行访问了。当然,这里只是一个例子,更多的功能处理有待于我们在实践中加以处理。
http://dotnet.aspx.cc/article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/comment.aspx
http://dotnet.aspx.cc/article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/new.aspx
http://dotnet.aspx.cc/article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/edit.aspx
http://dotnet.aspx.cc/article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/read.aspx
http://dotnet.aspx.cc/article/8d01fd5e-b2c1-40f5-8cea-bc2197fb9bd8/print.aspx
以上例子只是简单地进行了说明,实际应用中,还有更多的东西需要考虑,更多的信息可以参考如下的链接:
ASP.NET
路由(http://msdn.microsoft.com/zh-cn/library/cc668201.aspx)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15723462/viewspace-625302/
,如需转载,请注明出处,否则将追究法律责任。