在ASP.NET中重写URL的代码

时间:2021-05-25

经常有人请我指导应该如何动态地“重写”URL,以在他们的ASP.NETweb应用中发布比较干净的URL端点。这个博客帖子概述了几个方法,你可以用来在ASP.NET中干净地映射或重写URL,以及按照你自己的需求组织你的URL的结构。

为什么URL映射和重写很重要?
下面是开发人员想要对URL有更大的灵活性的最常见的场景:

1)处理这样的情形:你要更改你的web应用中网页的结构,但你同时也要确保在你移动网页后,那些被人收藏的老URL不会成为死链接。重写URL允许你透明地将请求转交到新的网页地址而不出错。

2)在象Google,Yahoo和Live这样的搜索引擎中提高你网站上网页的搜索相关性。具体地来说,URL重写经常能使你在你网站上网页的URL里更加容易地嵌入关键词,这么做往往会增加别人点击你的链接的机会。从使用查询字符串参数到使用完全限定(fullyqualified)的URL也能在某些情形下提高你在搜索引擎结果中的优先顺序。使用强制referring链接使用同样的大小写(samecase)和URL入口(譬如,使用weblogs.asp.net/scottgu而不是weblogs.asp.net/scottgu/default.aspx)的技术也能避免因跨越多个URL而造成的网页排名(pagerank)的降低(avoiddilutingyourpagerankacrossmultipleURLs),从而增加你的搜索结果。

在一个搜索引擎日渐驱动网站访问量的世界里,在你的网页排名上稍微得到一些提高就能给你的业务带来不错的投资回报(ROI)。逐渐地,这驱使开发人员使用URL重写以及其他SEO(搜索引擎优化)技术来优化网站(注,SEO是个步调很快的空间,增加你的搜索相关性的建议月月在演变)。想了解一些关于搜索引擎优化方面好的建议的话,我建议你阅读一下《SSWRulestoBetterGoogleRankings(SSW的提高Google排名之要领)》,以及MarketPosition关于《howURLscanaffecttopsearchengineranking(URL会如何影响顶级搜索引擎排名)》的文章。

例程的URL重写场景
为这个博客贴子起见,我将假设我们将在一个应用里建造一套电子商务的产品目录网页,产品是按种类来组织的(譬如,图书,录像,CD,DVD等等)。

让我们假定一开始我们有个网页叫Products.aspx,通过查询字符串参数接受一个类别名称,相应地过滤显示的产品。与这个Products.aspx网页对应类别的URL看上去象这样:

http://)).+
RewriteRule.*\.(?:gif|jpg|jpeg|png)/images/block.jpg[I,O]

一定要去读一下Scott和Jeff的贴子以了解这些ISAPI模块的详情,以及你都能用它们做些什么。

注:使用ISAPI过滤器的一个坏处是,共享主机环境一般不允许你安装这样的组件,所以你要用它们的话,你要么需要一个专用的虚拟主机服务器,要么需要一个专用的主机服务器。但,如果你有一个主机计划允许你安装ISAPI的话,这会在IIS5/6下会提供最大的灵活性,让你过渡到IIS7推出为止。

在URL重写里处理ASP.NETPostBack
大家在使用ASP.NET和重写URL时经常遇到的一个疑难杂症跟处理postback场景有关。具体地来说,当你在一个网页上放置一个<formrunat="server">控件时,ASP.NET会自动地默认输出标识的action属性指向当前所在页面。当使用URL重写时,会出现这样的问题,<form>控件显示的URL不是原先请求的URL(譬如,/products/books),而是重写过后的URL(譬如,/products.aspx?category=books)。这意味着,当你做一个postback到服务器时,URL不再是你原先干净利落的那个了。

在ASP.NET1.0和1.1中,大家经常诉诸于继承<form>控件生成他们自己的控件,来正确地输出要使用的action属性。虽然这可以工作,但结果有点乱,因为这意味着你需要更新你所有的页面来使用这个另外的表单控件,而且有时在VisualStudio所见即所得设计器里也会遇上问题。

好消息是,在ASP.NET2.0中,有个比较干净的诀窍你可以用来重写<form>控件的action属性。具体地来说,你可利用新的ASP.NET2.0控件适配器扩展架构来定制控件的输出,用你提供的值来覆盖action属性的值。这不要求在你的.aspx页面里做任何编码改动,而只要在你的/app_browsers文件夹里添加一个.browser文件,注册使用一个控件适配类即可输出新的action属性。




你可在这里查看一个我创建的样例实现,其展示了该如何实现与URL重写协作的表单控件适配器(FormControlAdapter)。它在我上面使用的第一个(Request.PathInfo),第二个方法(UrlRewriter.Net模块)中都工作,它使用Request的RawUrl属性获取原先没改写过的URL来显示。而在第四个方法(ISAPIRewrite过滤器)中,你可以获取ISAPI过滤器保存在Request.ServerVariables["HTTP_X_REWRITE_URL"]中的原先的URL值。

我上面的FormRewriter类实现在标准的ASP.NET和ASP.NETAJAX1.0网页上应该都工作(如果你遇上问题的话,告诉我一声)。

正确地处理CSS和图像引用
不少人在第一次使用URL重写时,有时会遇上一个疑难杂症,就是他们发现他们的图像和CSS样式表引用有时会停止工作。这是因为他们在HTML网页里有对这些文件的相对引用,当你开始在应用里重写URL时,你需要意识到浏览器经常会在不同的逻辑层次结构层上(logicalhierarchylevels)请求文件,而不是实际存储在服务器上的东西。

譬如,如果我们上面的/products.aspx网页对.aspx网页里的logo.jpg有一个相对引用,但是通过/products/books.aspx这个URL来请求的,那么浏览器在显示网页时,将会发出一个对/products/logo.jpg的请求,而不是对/logo.jpg的请求。要正确地引用这个文件,确认你用根目录限定了(rootqualify)CSS和图像引用(“/style.css”,而不是“style.css”)。对于ASP.NET控件,你也可以使用“~”句法从你应用的根目录来引用文件(譬如,<asp:imageimageurl="~/images/logo.jpg"runat="server"/>)。

希望本文对你有所帮助,

Scott

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章