灵活的URL重写可以让你的网站增加可用性和专业性。在帮助网站更好的被搜索引擎索引收录方面,这也是一个重要的因素。在本篇文章中,我将带你了解如何在ASP.NET中简单的实现URL重写,以及一些常见问题的解决办法。我还将说明为什么URL重写如此重要,以及如何使用它来增强你的网站。
什么是URL重写?
URL重写就是首先获得一个进入的URL请求然后把它重新写成网站可以处理的另一个URL的过程。举个例子来说,如果通过浏览器进来的URL是“www.mysite.com/UserProfile/1.aspx”,那么它可以被重写成 “www.mysite.com/UserProfile.aspx?ID=1”这样的URL,这样的网址可以更好的被网站所阅读。
重写URL是非常有用的一个功能,因为它可以让你提高搜索引擎阅读和索引你的网站的能力;而且在你改变了自己的网站结构后,无需要求用户修改他们的书签,无需其他网站修改它们的友情链接;它还可以提高你的网站的安全性;而且通常会让你的网站更加便于使用和更专业。关于它的好处,我将在本篇文章的“如何利用URL重写”部分来详细的说明。
如何实现URL重写
URL重写可以通过编程的方式来实现。ASP.NET中的Contex.RewritePath()方法可以让你从程序中实现重写请求的URL。一旦重写后,系统将使用新的路径来继续执行这个请求。
在Global.asax文件的Application_BeginRequest()方法中,你需要增加代码来阅读进来的路径,然后根据一个或多个URL重写规则来成需要进一步处理的路径。下面的例子执行以下URL重写规则:
输入的URL 重写的URL
~/UserAccount./Old.aspx ~/UserAccount./New.aspx
~/UserAccount./{UserId}.aspx ~/UserAccount..aspx?ID={UserId}
代码清单1:使用Contex.RewritePath()实现URL重写
void Application_BeginRequest(object sender, EventArgs e)
{
String path = Request.Url.ToString();
if (Regex.IsMatch(path, "/URLRewriting/OldUrl.aspx",
RegexOptions.IgnoreCase))
{
Context.RewritePath("/URLRewriting/NewUrl.aspx");
}
else if (Regex.IsMatch(path, "/URLRewriting/UserAccount/(.+).aspx",
RegexOptions.IgnoreCase))
{
String idString =
path.Substring(path.LastIndexOf('/') + 1,
path.Length - path.LastIndexOf('/') - 6);
Context.RewritePath("/URLRewriting/UserAccount.aspx?id=" +
idString);
}
}
在这个例子中,每次一个新的请求被处理的时候,它将首先查看这个Application_BeginRequest()。通过使用Request.Url属性来获得输入的URL路径,然后通过正则表达式来应用网站URL重写规则,匹配到期望的输入网址后,将它们重写成你希望转向的网址。
当重写规则比较简单且规模比较小的时候,使用Context.RewritePath() 方法以编程的方式重写URL效果比较不错,但是一些大型网站通常有非常多的URL重写规则。手工方式对所有这些重写规则进行编程可能是一件麻烦且容易出错的方法。
比如:浏览器发来请求 http://localhost:80/URLRewriter/1.html ,
服务器自动将这个请求中定向为http://localhost:80/URLRewriter/url.aspx?id=1
URLRewriter下载编译后提取其中的URLRewriter.dll和ActionlessForm.dll
一、URL重写
项目引用URLRewriter.dll
web.config配置:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> <? xml version="1.0" ?>
< configuration xmlns ="http://schemas.microsoft.com/.NetConfiguration/v2.0" >
< configSections >
< section name ="RewriterConfig" type ="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />
</ configSections >
< RewriterConfig >
< Rules >
< RewriterRule >
< LookFor > ~/URLRewriter/(.[0-9]*)\.html </ LookFor >
< SendTo > ~/URLRewriter/url.aspx?id=$1 </ SendTo >
</ RewriterRule >
< RewriterRule >
< LookFor > ~/web </ LookFor >
< SendTo > ~/URLRewriter/url.aspx </ SendTo >
</ RewriterRule >
</ Rules >
</ RewriterConfig >
< system.web >
< httpHandlers >
<!-- URLRewriter begin 使用 HTTP 处理程序执行重写 -->
<!-- <add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />
<add verb="*" path="*.html" type="URLRewriter.RewriterFactoryHandler, URLRewriter" /> -->
<!-- URLRewriter end -->
</ httpHandlers >
< httpModules >
<!-- URLRewriter begin 使用 HTTP 模块执行重写 -->
< add type ="URLRewriter.ModuleRewriter, URLRewriter" name ="ModuleRewriter" />
<!-- URLRewriter end -->
</ httpModules >
</ system.web >
</ configuration >
IIS配置:
网站--属性--主目录--配置--插入--C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
将文件是否存在 勾去掉
二、处理PostBack回发
ActionlessForm.dll以重写Form的方式用于处理PostBack回发后URL变为原始地址
项目引用ActionlessForm.dll在页面中注册一下
<%@ Register TagPrefix="skm" Namespace="ActionlessForm" Assembly="ActionlessForm" %>
将页面中的<form runat="server"></form>替换成:<skm:form id="form1" runat="server"></skm:form>
注:以这种方式处理回发将会在设计器中查看的时候为错误提示Form不可用
所以采用以下方法处理:
在微软的URLRewriter类库中添加以下类之后编译
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
/// <summary>
/// FormRewriter 的摘要说明
/// </summary>
namespace URLRewriter.Form
{
public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
public FormRewriterControlAdapter()
{
}
protected override void Render(HtmlTextWriter writer)
{
base .Render( new RewriteFormHtmlTextWriter(writer));
}
}
public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
: base (writer)
{
base .InnerWriter = writer.InnerWriter;
}
public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)
: base (writer)
{
base .InnerWriter = writer;
}
public override void WriteAttribute( string name, string value, bool fEncode)
{
// If the attribute we are writing is the "action" attribute, and we are not on a sub-control,
// then replace the value to write with the raw URL of the request - which ensures that we'll
// preserve the PathInfo value on postback scenarios
if (name == " action " )
{
HttpContext context = HttpContext.Current;
if (context.Items[ " ActionAlreadyWritten " ] == null )
{
// We will use the Request.RawUrl property within ASP.NET to retrieve the origional
// URL before it was re-written.
value = context.Request.RawUrl;
// Indicate that we've already rewritten the <form>'s action attribute to prevent
// us from rewriting a sub-control under the <form> control
context.Items[ " ActionAlreadyWritten " ] = true ;
}
}
base .WriteAttribute(name, value, fEncode);
}
}
}
在App_Browsers文件夹下创建Form.browser
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--> < browsers >
< browser refID ="Default" >
< controlAdapters >
< adapter controlType ="System.Web.UI.HtmlControls.HtmlForm"
adapterType ="URLRewriter.Form.FormRewriterControlAdapter" />
</ controlAdapters >
</ browser >
</ browsers >
这样就不需要引用ActionlessForm.dll也不需要改变Form了,只要引用URLRewriter.dll就可以了
三、在处理重写成html的时候本来网站中的html页面将会不能使用
使用以上方式将不存在找个问题
如果还不行可以在<compilation debug="true">节点下添加
<buildProviders>
<add extension=".html" type="System.Web.Compilation.PageBuildProvider" />
</buildProviders>
在<httpHandlers>节点下添加(如果之前使用的是http处理程序执行重写的,请写在前面)
<add path="*.html" verb="*" type="System.Web.UI.PageHandlerFactory" validate="true"/>
以下为IIS7.0配置方式
IIS7不再使用URLRewriter.dll组件了,请使用IIS7的URLWRITER,下载rewrite_2.0_rtw并进行安装,配置