ISAPI_Rewrite3.1于MVC站点下,在IIS7跳转成功,但在IIS6跳转失败,有后缀URL和有后缀URL处理方式不同。
2014-04-18 12:05
239 查看
一、问题描述
老商铺使用Asp.NET Form,重构后使用Asp.NET MVC。需要对老商铺的链接进行跳转。介于老商铺之前已经使用ISAPI_Rewrite3.1做过伪静态处理,跳转规则需要处理两种链接(老商铺的英文拼写是错误的-_-!):
localhost:8008/compayinfo/B5BD5324-D7CD-448A-A499-B01808CCFAB6 localhost:8008/companyinfo.aspx?Uid=B5BD5324-D7CD-448A-A499-B01808CCFAB6
在IIS7下,使用以下跳转规则,没有问题:
RewriteRule ^/compayinfo/(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})/?$ /Home/Company/$1 [NC] RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$ /Home/Company/$1 [NC]
但是在IIS6下,无法跳转。无奈准备将跳转规则硬编码进MVC路由。
悲催的是,写完代码调试的时候才发现,原来NVC的路由中不允许出现问号:
路由 URL 不能以“/”或“~”字符开头,并且不能包含“?”字符。
本来就觉得硬编码很不爽,现在又发现这种限制,马上回头查找IIS6下跳转失败的原因。
二、查找资料
在baidu了几篇,bing了十几篇,google被重置,后得知:ASP.NET 4.0在安装的时候,会在IIS6注册一个ISAPI Filter,叫做”aspnet_filter.dll”,ISAPI Filter会先于ISAPI处理程序前执行,它会在所有的的无后缀的URL后面加一串字符“/eurl.axd/GUID”, 同时ASP.NET 4.0还会在IIS默认添加一个请求映射规则“*.axd”,映射到aspnet_isapi.dll。此时,所有的无后缀URL加上“/eurl.axd/GUID”后都会变成带.axd后缀,这样就匹配*.axd的映射规则进行ASP.NET的处理通道。在进入ASP.NET通道后,ASP.NET处理程序会删除掉“/eurl.axd/GUID”,让它还原到无后缀的原始情况,并且不会对后续的请求处理带来任何影响。此时,所有的无后缀请求,就进入了ASP.NET的处理通道中,在默认情况下,ASP.NET4.0的全局的web.config中配置了DefaultHttpHandler来接收无后缀的URL请求,但是我们也可以随意更换默认处理程序(比如ASP.NET MVC处理程序)来处理无后缀的URL请求。
提供的解决方案也无外乎:
修改注册表:
在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0(64位:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\4.0.30319.0)下,添加键值名为“EnableExtensionlessUrls” 类型为“DWORD”的键值,并设置值为“0”。然后在cmd中运行“IISRESET”,重启IIS以读取注册表修改后的内容。
注:此项修改就是关闭 ASP.NET 4.0对无扩展URL的处理,若将此项键值设为“1”则开启。
在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\4.0.30319.0(64位:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\4.0.30319.0)下,添加键值名为“EnableExtensionlessUrls” 类型为“DWORD”的键值,并设置值为“0”。然后在cmd中运行“IISRESET”,重启IIS以读取注册表修改后的内容。
注:此项修改就是关闭 ASP.NET 4.0对无扩展URL的处理,若将此项键值设为“1”则开启。
或者使用.NET2的应用程序池,或者自定义一个重写模块。
问题是我连修改IIS的权限都没有,更何况注册表了。自定义重写模块也太麻烦了。
三、尝试解决
经过N多次尝试,推测出请求的处理顺序如下:对于无后缀URL:compayinfo/B5BD5324-D7CD-448A-A499-B01808CCFAB6
1.首先被aspnet_filter处理为:compayinfo/B5BD5324-D7CD-448A-A499-B01808CCFAB6/eurl.axd/GUID
2.然后进入ISAPI_Rewrite,进行重定向
3.接着根据“*.axd”的映射规则将请求交给aspnet_isapi
4.进而在aspnet_isapi中移除后缀/eurl.axd/GUID
5.最后进行后续处理
可以看出,对于无后缀URL,在进行重定向时,需要处理被添加的后缀:
RewriteRule ^/compayinfo/(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(/eurl.axd/.*)$ /Home/Company/$1$2 [NC]
测试成功!立马将该方法应用于有后缀URL,进行尝试,惨遭失败:
RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$ /favicon.ico [NC] RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$ /Home/Company/$1 [NC] RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(/eurl.axd/.*)$ /Home/Company/$1 [NC] RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$ /Home/Company/$1/eurl.axd/ [NC] RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$ /Home/Company/$1/eurl.axd/0 [NC] RewriteRule ^/companyinfo.aspx\?Uid=(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$ /Home/Company/$1/eurl.axd0/ [NC]
第一条成功。
第二条失败,出现IIS404。
第三条失败,出现Asp.NET404,找不到/companyinfo.aspx。
第四条成功,但它匹配到了我的一条路由规则“{controller}/{action}/{Identifie}/{id}”,其中id的值为“eurl.axd”
第五条失败,出现Asp.NET404,找不到/Home/Company/B5BD5324-D7CD-448A-A499-B01808CCFAB6/eurl.axd/0。
第六条失败,出现IIS404。
注:
以上内容编辑于2013-09-24 11:13,但一直放在草稿箱中忘了发布,今天才看到,发布一下。
另外,对于有后缀URL,因时间有限且并不特别需要,后并未深入研究。
相关文章推荐
- 自制Javascript分页插件,支持AJAX加载和URL带参跳转两种初始化方式,可用于同一页面的多个分页和不同页面的调用
- IIS5、IIS6、IIS7的ASP.net 请求处理过程比较<转>
- 在IIS6上部署MVC站点,Nhiernate数据库底层
- ASP.NET mvc下在Controller下action的跳转方式
- ASP.NET MVC 3.0:基于Ajax的表单提交,A页面认证失败后页面被强转至登录页面,待登录成功将如何回到A页面?
- Asp.net中处理一个站点不同Web应用共享Session的问题
- IIS7 里注册HttpModule和IIS6 里注册时候 在WEB.CONFIG里有所不同
- 使用url快捷方式 打开不同的浏览器
- IIS7.5(经典/集成),IIS6,asp.net 4.0下配置Url映射(asp.net mvc)
- Codeigniter实现处理用户登录验证后的URL跳转
- 安卓访问网络常用的3种方式(httpClient, httpUrlConnection,android-query ajax)及cookie处理
- resetlogs方式打开数据库,某数据文件需要recover,恢复失败的处理方式
- iphone,UIImageView展现不同途径的图片的不同处理方式
- jQuery使用Base64 生成图片预览和java后台不同的接收处理方式
- windows和linux下使用python2.7 urllib.urlopen+beautifulsoup打开12306网站订票页面表现不同,前者报错ssl认证失败,后者成功
- 传统的web和MVC处理方式
- [转贴]IIS5、IIS6、IIS7的ASP.net 请求处理过程比较
- C++中new失败的三种处理方式
- sd_setImageWithURL加载图片失败原因以及处理方法
- IIS5、IIS6、IIS7的ASP.net 请求处理过程比较