站点地图的设计基于一个简单的原则:每个入口具有一个单独的 URL。虽然可以增加查询字符串区分 URL,但在很多网站 Web 表单和站点地图入口是一一对应的。
当这个原则不适用时,ASP.NET 有两个工具可以解决这一问题:
- URL 映射。它以整洁、合乎逻辑的方式把 URL 映射到其他地址。(适合解决一次性的重定向问题,例如,映射新近移动过的页面)
- URL 路由。它执行同样的任务,但更加精巧和灵活。(可以用作处理许多页面的复杂重定向系统的基础)
URL 映射
ASP.NET 映射的幕后的原理是把一个请求的 URL 映射到一个不同的 URL。映射规则保存在 web.config 文件中。它们在任何其他处理发生之前会首先被应用。
在 web.config 文件的 <urlMappings> 节中定义 URL 映射,需要提供 请求URL(url 特性) 和 目标URL(mappedUrl 特性)。
<system.web>
<urlMappings enabled="true">
<add url="~/Category.aspx" mappedUrl="~/Default.aspx?category=default"/>
<add url="~/Software.aspx" mappedUrl="~/Default.aspx?category=software"/>
</urlMappings>
</system.web>
使用 URL 映射,重定向的实现和 Server.Transfer()方法一样,不会有服务器和客户端之间的往返,浏览器的 URL 仍会显示原是请求的 URL。对于代码,Request.Path 和 Request.QueryString 反映的是新的 URL,Request.RawUrl 反悔被请求的原始的友好 RUL。
URL 路由
路由是 ASP.NET MVC 的核心功能,不过 ASP.NET 也允许在由 Web 表单组成的传统 Web 应用程序里使用相同的路由技术。路由不是在 web.config 中设置的,而是通过代码实现的。一般,会在 global.asax 文件的 Application_Start()里为应用程序注册所有路由。
使用 System.Web.Routing 命名空间中的 RouteTable 类注册路由。它有一个静态属性 Routes,这个属性拥有为应用程序定义的一系列 Route 对象。起初,这个集合是空的,但是可以调用 MapPageRoute()方法创建自定义的路由,这个方法有 3 个参数:
- routeName:标识路由的名称,可以是你希望的任意值。
- routeUrl:指定浏览器使用的 URL 格式。通常会由一个或多个变量信息组成,例如 /products/4312 这样的 URL 请求某个产品页面。
- physicalFile:它是目标的 Web 表单(使用路由时用户被重定向的地址)。
下面这个示例在 Web 应用程序第一次启动时添加两个路由:
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapPageRoute("product-details", "product/{productID}", "~/productInfo.aspx");
RouteTable.Routes.MapPageRoute("product-in-category", "product/category/{categoryID}", "~/products.aspx");
// 路由 URL 可以有一个或多个参数,用花括号中的占位符表示
// 这里演示的第一个路由有一个名为 productID 的参数
// 这段信息将由 URL 取得并被传送给目标页面
}
这个 URL 使用该路由请求 ID 为 IF_00345 的产品:
接收到请求后,ASP.NET 路由架构把用户重定向到 productInfo.aspx 页面。所有参数通过 Page.RouteData 属性提供,它最有用的属性是 Values 集合,该集合按名称索引提供原始请求的所有参数。
这里是目标页的代码片段:
public partial class ProductInfo : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
object obj = Page.RouteData.Values["productID"];
if (obj != null)
{
lblInfo.Text = "You requested " + obj.ToString();
}
}
}
虽然可以硬编码这种请求格式的 URL,不过也可使用 Page 类的辅助方法自动得到 URL 的格式,从而避免潜在的错误。下面的代码检查路由(通过注册的名称),并提供参数信息,最后得到返回的对应的 URL:
protected void Page_Load(object sender, EventArgs e)
{
HyperLink1.NavigateUrl = Page.GetRouteUrl("product-details", new { productID = "AAA168" });
}