使用UrlRewriter进行Url重写的完整解决方案[转]
Setp 1:
下载UrlRewriter => http://urlrewriter.net/
Setp 2:
将其添加到Web项目的Bin目录下
Setp 3:
配置:打开web.config,在configSecions中添加sectionHandler:
RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter" />
添加这个section是为了它能够处理web.config中的节;然后对UrlRewriter配置url重写规则:
<rewrite url=”~/lmh$” to=”~/Users.aspx?user=lmh” processing=”stop” />
</rewriter>
url是可以使用正则表达式的。比如上面的例子,就是将http://www.***.net/lmh重写到http://www.***.net/Users.aspx?user=lmh,$在正则表达式中表示是串的结束,也就是说http://www.***.net/lmhe是不会被重写到to后的地址的,如果把$去掉则可以。
Setp 4:
使rewriter生效:UrlRewriter是在HttpModule中做url重写的,要使重写生效,就得先把HttpModule添加到web.config中:
<add name="UrlRewriter" type="Intelligencia.UrlRewriter.RewriterHttpModule, Intelligencia.UrlRewriter"/>
</httpModules>
Setp 5:
让ReWriter有机会重写Url: 当iis收到一个请求时,并不是都会扔给asp.net(aspnet_isapi.dll)来处理,比如静态html,默认情况下,当请求html页面时,iis直接就把结果抛给了客户端,之所以.aspx页面会被asp.net引擎处理,是因为在iis有进行处理程序映射,.aspx被映射到aspnet_isapi.dll,所以当iis收到请求时,先看后缀名,如果是aspx,那就把它交给aspnet_isapi.dll来处理。因为UrlRewriter是asp.net级别的重写组件,所以,假如要想执行setp3中例子那样的重写,得先让UrlRewriter有机会收到这个地址的请求才行(默认UrlRewriter是没机会处理这个url的,因为iis收到这个地址的请求时,因为它没有映射到aspnet_isapi.dll,所以会直接抛出404找不到的错误,因此,要替它做这个映射。打开iis,在属性中有这一项,我们可以让*映射到aspnet_isapi.dll,这样所有的文件都交给asp.net来处理了,UrlRewriter也就有机会出手了。
如果用的是IIS7.0,则不用这么麻烦,整个Setp4可以简化为:在web.config中的节的节中添加上UrlRewriter:.webserver>
这会保证所有的请求都会经过asp.net的这个Module。
现在,重写就算基本完成了,但有几个问题:
Problem 1:
图片可能不显示:如果进行Url Rewirte并且页面中的图片引用是使用相对路径的话,很可能会发现图片无效了,这是因为,假如/Users/lmh会被重写为/Users.aspx?user=lmh,而Users.aspx上有一张图片,放在相同目录下:logo.gif,(Users.aspx中是<img src='logo.gif' />)那当请求/Users/lmh时,浏览器对logo.gif的请求的路径将变成/Users/logo.gif,而实际上logo.gif是要用/logo.gif才能请求得到的,所以,为了保证Url rewrite后不会出现这个问题,需要使用<img src='/logo.gif' />,但是当使用UrlRewriter时,对于Css,如果代码中是,而实际用Users/lmh去请求的话,会发现其实已经变成了,而图片,如果是用的服务器控件的话,也可以继续使用相对路径,就不存在标题中的问题。
Problem 2:
Asp.net的postback会导致真实地址又被嚗光:还是setp3的例子,假设Users.aspx中有一个服务器按钮控件,当第一次请求时,确实OK,但是一旦点击了那个按钮,地址栏又变成了http://www.***.net/Users.aspx?user=lmh,原因是asp.net的服务器form控件的action默认都是指定当前页面地址的,虽然我们收到的请求是…/lmh,但经过UrlRewrite后,asp.net处理的已经是真实的地址:…/Users.aspx?user=lmh,所以在form被Render时,action会是../Users.aspx?user=lmh,那么,要解决这个问题,就是让form的action的值也被render为请求的地址,这个网上已经有答案了,就是利用ControlAdapter(写在App_Code中即可,不过为了重用,可以放到类库项目中):
1 public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
2 {
3 protected override void Render(HtmlTextWriter writer)
4 {
5 base.Render(new RewriteFormHtmlTextWriter(writer));
6 }
7 }
8
9 public class RewriteFormHtmlTextWriter : HtmlTextWriter
10 {
11 public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
12 : base(writer)
13 {
14 this.InnerWriter = writer.InnerWriter;
15 }
16
17 public override void WriteAttribute(string name, string value, bool fEncode)
18 {
19 if (name == "action")
20 {
21 HttpContext context = HttpContext.Current;
22
23 value = context.Request.RawUrl;
24 }
25 base.WriteAttribute(name, value, fEncode);
26 }
27 }
这段代码是来自Jeffery Zhao的博客文章(我去掉了其中一些代码,只保留了保证会工作的最基本代码)。
需要说明的一点是:HtmlTextWriter有两个WriteAttribute方法:
public virtual void WriteAttribute(string name, string value, bool fEncode)
public virtual void WriteAttribute(string name, string value)
重写下面的那个WriteAttribute是不能成功的,必须重写上面那个方法。为什么呢?先调试看看。
会发现如果重写的是上面那个方法,则会有一次传进来的name值是"action",如我所愿,而重写下面那个方法则没发现传进来值是”action”的name参数。这是怎么搞的?
首先我们要知道,下面那个方法其实是简单的调用了上面的WriteAttribute :
public virtual void WriteAttribute(string name, string value) {
WriteAttribute(name, value, false /*encode*/);
}
这是framework中的源码。那么,我们所可以猜测到的,就是action这个属性不是通过调用WriteAttribute(“action”, “…”)来渲染的,而是直接调用WrtiteAttribute(“action”, “…”, …),那我们就打开HtmlForm的源代码看看吧(没有源代码的可以用Reflector看),找到HtmlForm.RenderAttributes(HtmlTextWrtier writer)方法,其中有几行:
writer.WriteAttribute("method", Method);
Attributes.Remove("method");
// Encode the action attribute - ASURT 66784
writer.WriteAttribute("action", GetActionAttribute(), true /*encode*/);
Attributes.Remove("action");
我们重点看的是上面加粗并下划线的那两行,可以很清楚的看到,当渲染”method”属性时,只是调用了
public virtual void WriteAttribute(string name, string value)
而渲染action属性则是调用了
public virtual void WriteAttribute(string name, string value, bool fEncode)
那么,答案也就浮出水面了。
接下来,我们要让这个Adapter起作用(上面之所以可以调试,是因为我已经让其起作用了,只是还没写出来)。添加Asp.net Folder:App_Browses,新建一个browser文件:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="FormRewriterControlAdapter"/>
</controlAdapters>
</browser>
</browsers>
因为上面的FormRewriterControlAdapter是写在App_Code中的,所以不需要添加命名空间。
上面说的是一种防止postback后地址还原的办法,还有一种办法就是利用UrlRewriter自带的form控件,这个方法还不需要写这么多代码:
首先,要先注册控件:
然后用<rewriter:form runat="server"></form>代替掉原来的<form runat="server"></form>就可以了。
这么一来,使用UrlRewriter进行asp.net级别的UrlRewrite就弄好了。
from:http://www.cnblogs.com/mouhong-lin/archive/2008/08/07/1262965.html
使用UrlRewriter进行Url重写的完整解决方案[转]相关推荐
- 使用URLRewriter实现URL重写
优点 1)隐藏真实URL,提高安全性 2)更加友好的URL,好记(看博客园就行知道啦) 3)便于搜素引擎收录 ......... 可能的缺点 使用URL重写可能导致: 1)图片路径的问题 2)CSS路 ...
- asp.net 使用UrlRewritingNet.UrlRewriter组件URL重写,伪静态详解
目录 URL重写的业务需求 ReWritingNet组件主要功能 配置IIS(IIS7/8环境下) 程序代码 重写规则 一,URL重写的业务需求 顾客可以直接用浏览器bookmark功能将页面连结储存 ...
- 使用URLRewriter进行URL重写失效
运行环境:ASP.NET 2.0 + Windows 2003 SP2 需求描述:站点中许多菜单都调用了相同的页面,通过URL参数区别不同的功能.目前客户希望进行搜索引擎优化(SEO),需 ...
- URL重写(使用微软URLRewriter)
写在前面的话:经常在浏览网页时看到类似这样的URLhttp://www.cnblogs.com/Ferry/archive/2009/06/19/1506770.html,1506770.html是实 ...
- asp.net用url重写URLReWriter实现任意二级域名 (转)
asp.net用url重写URLReWriter实现任意二级域名 Asp.net 用url重写(URLReWriter)实现任意二级域名 好久没有写技术文章,如果大家看不明白,就多看几篇,汗,或者,在 ...
- java urlrewriter_java url重写技术(UrlReWriter)
现在url重写技术用的越来越广泛了,很高兴今天和各位网友分享一下: 首先我们要从网上下一个UrlReWriter jar包 现在地址进不了,我这里有一个3.0版本的,文章底有下载地址,大家可以去下载 ...
- asp.net url 重写解决方案
大家都知道很多网站特别是大型网站现在都用了url伪静态重写来实现用户的易用性和美观性,比如这个网站 http://www.xintaifcw.com 很明显采用了url重写,里面的所有文章内容都是用了 ...
- asp.net用url重写URLReWriter实现任意二级域名(续)
asp.net用url重写URLReWriter实现任意二级域名(续) 更高级的内容看这里: http://www.cnblogs.com/notus/archive/2007/03/13/67322 ...
- 在 ASP.NET 中执行 URL 重写
在 ASP.NET 中执行 URL 重写 发布日期: 8/23/2004 | 更新日期: 8/23/2004 Scott Mitchell 4GuysFromRolla.com 适用范围: Micro ...
最新文章
- 4-1 图像特效介绍
- 【PAT乙级】1060 爱丁顿数 (25 分)
- 【思维导图】Python中常用的8种字符串操作
- PowerTip of the Day from powershell.com上周汇总(六)
- MVC 1.0的可能方法
- bat循环导oracle,Oracle备份恢复与批处理文件实操
- DevExpress 隐藏Ribbon中barbuttonItem的SuperTip(2)
- 一种特殊的多语言解决方案
- 【无机纳米材料科研制图——Photoshop 0404】PS排列扫描透射电子显微镜图TEM/STEM
- HTML与Java组合使用_【自学java笔记#第五十四天#】javaweb day02 html和css的组合使用...
- O2O模式成功案例分享 汲取精华化为己用
- USB总线-Linux内核USB3.0设备控制器之dwc3 gadget驱动初始化过程分析(五)
- 腾讯云:轻量服务器8核16G18M配置性能及限制条件说明
- 鼠标光标一直在闪烁_便携有个性,功能强大,可配戴在手指上的键盘鼠标
- Java-多线程的使用
- python【模块】xml.etree.ElementTree 解析 xml
- 【实验室预约平台系统——开题报告 分享(仅供参考呀)】
- php k线15分钟 30分钟,5分钟K线、15分钟K线、30分钟K线和60分钟K线
- 在 Java 中检查空字符串或空白字符串
- Windows安装You-get详细教程和问题解决分享
热门文章
- calendar.getinstance()获取的是什么时间_时间管理技能培训.ppt
- 计算方法c语言上机作业,考研复试-----C语言上机操作(三)
- 唐山师范学院计算机科学与技术地址,2021年唐山师范学院有几个校区,大一新生在哪个校区...
- php字符串如何比较大小写,PHP字符串函数strcmp(二进制安全比较字符串,区分大小写)...
- 2.5 不匹配数据划分的偏差和方差
- win7查看tomcat端口_想研究Tomcat性能调优,看这篇就够了
- python安装wx模板_windows下wxPython开发环境安装与配置方法
- tidb使用坑记录TiDB和Mysql的sql差异总结
- Linux单用户模式(修改密码、运行级别)方法详解
- Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere