|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
既然话题已经抄起,我打算今晚发篇博文再引导一下舆论方向,使它再火两天,抛砖引玉,而且赵劼先生一直在跟帖,使.NET阵营的我感到万分难得。 约莫一年半前,我在博客上写过一系列关于URLRewrite的文章(2、3、4),把ASP.NET平台长进行URLRewrit的体例和各自地特性举行了较为具体的形貌。应当来讲,已讲的十分详细,能够应对90%的情形。实在IISRewrite的道理十分简单了解,举行一些复杂的变更和揣度以后,即可以得出一些成绩的缘故原由息争决计划。如今我们就来看一个实在案例:在ASP.NETMVC中利用IIS级其余URLRewrite。
在事先的文章中我谈到,URLRewrite分有IIS级别和ASP.NET两种级别,而且各有各的特性和限定。在ASP.NETMVC中我们经常使用的体例是ASP.NET级其余URLRouting,它的感化是从URL中捕捉数据并交给程序利用(固然另有“机关”的功效,稍候再谈)。因而,在ASP.NETMVC中我们常常不必要利用ASP.NET级其余URLRewrite。而现在利用IIS级其余URLRewrite,也恰是由于有某些特别成绩没法躲避才“不得已而为之”的。
以下触及到的URL都以http://51programming.com为例,这个域名已被我泛剖析为127.0.0.1,假如您必要的话能够用它来做实行。
在很多年前,一个URL的Path就是一般的路径,而静态的参数,如查询路径,是经由过程QueryString供应的,比方:- http://kuqin.com/products?keywords=helloworld
复制代码 为了不搅浑,在这里我们先来廓清一些观点。甚么是URL,甚么是Path,而甚么是QueryString。比方在下面的地点,这三者分离是:
- URL:http://kuqin.com/products?keywords=helloworld
- Path:http://kuqin.com/products
- QueryString:keywords=helloworld
厥后SEO衰亡以后,有人说如许的“静态地点”倒霉于搜刮引擎中的权重优化,因而倡议把关头字作为Path的一部分。因而就呈现了如许的URL:- http://kuqin.com/products/helloworld
复制代码 这么看来成绩其实不年夜,可是您要晓得,关头字常常是由用户输出的,大概会输出特别字符。比方,假如用户输出了“200%”作为关头字,则两种情势下的URL就分离是:- http://kuqin.com/products?keywords=200%25http://kuqin.com/products/200%25
复制代码 假如您实验一下即可以晓得,第一个URL能够一般会见,而第二个URL便会激发BadRequest非常:
<br> 这是由于URL的Path部分呈现了特别字符,而这类字符只能呈现在QueryString中。
看到这个画面,您还意想到了甚么信息?在定位成绩的缘故原由,和想法办理成绩的时分,起首要明白的是究竟是那里呈现了成绩。比方看到这个画面,您应当分明地意想到一点:这是ASP.NET抛出的非常,换句话说,IIS并没有把它看成长短法的URL,它仍是老厚道实地将URL交给ASP.NETISAPI处置。因而,我们即可以动用IIS级其余URLRewrite,在进进ASP.NET实行引擎之前,就把URL交换成可承受的情势:- RewriteRule^/products/([^?]*)?(.+)/products?$2&keywords=$1[I,L,U]RewriteRule^/products/([^?]*)/products?keywords=$1[I,L,U]
复制代码 第一行应对的是带有QueryString的情形,而第二行则是没有QueryString的情形。这里用到的组件是IIRF(Ionic"sIsapiRewriteFilter),这是一款开源产物,一年半前的文章里我保举的也是这个,如今它已有了晋级。它的功效即是在进进ASP.NETISAPI之前,就将URL重写为其他情势:
<br> 底本在第3步会呈现的BadRequest,因为已在第2步被URLRewrite成正当的情势。因而残剩的处置也就没有任何成绩了。
这些内容在一年半前的文章内已提过,不外如今既然有了ASP.NETMVC,则事变又变得更加庞大。由于ASP.NETRouting除“婚配”URL的功效以外,还担当着“组装”URL的职责。因而,让ASP.NETRouting可以辨认出Rewrite后的URL不难,可是怎样同时让它又能够“组装”出Rewrite前的URL,这就必要一些小技能了。比方以下的Route设置只能辨认出URL输出(/products?keywords=xxx)但不克不及组装出我们必要的URL(/products/xxx):- routes.MapRoute("Product.List","products",new{controller="Product",action="List"});
复制代码 因而,我们必需这么做:- routes.MapRoute("Product.List","products/{*keywords}",new{controller="Product",action="List",keywords=""});
复制代码 请注重我们让keywords婚配Path后端全体内容,而因为我们又供应了keywords的默许值,因而即便是“/products”如许的Path输出,也能准确婚配到这条Route划定规矩——只不外此时的RouteValue中的keywords字段已不是用户输出的内容了(由于用户输出的/products/xxx,已被重写为/products?keywords=xxx)。换句话说,假如有以下的Action,那末它的keywords参数则永久是空字符串:- publicActionResultList(stringkeywords){...}
复制代码 幸亏,ASP.NETMVC中存在ModelBinder机制,我们能够编写一个ModelBinder来指定这个参数的猎取地位:- publicclassFromQueryBinder:IModelBinder{publicobjectBindModel(ControllerContextcontrollerContext,ModelBindingContextbindingContext){returncontrollerContext.HttpContext.Request.QueryString[bindingContext.ModelName];}}
复制代码 再将其使用到List的keywords参数上往:- publicActionResultList([ModelBinder(typeof(FromQueryBinder))]stringkeywords)
复制代码 因为参数名是keywords,因而bindingContext.ModelName也是keywords,因而从QueryString中即可以取到我们必要的内容了。至于在举行URL天生的时分,我们仍是能够之间一样增加一个keywords字段到RouteValue中往,因而在我们先前设置的Route划定规矩中便会组装成符合的Path了(即/products/xxx)。
在这个例子中,我们让keywords婚配Path后端全体内容,可是假如是Path两头某一段必要有特别字符怎样办呢?实在也一样,只是在举行URLRewrite的时分,必要在终极重写的时分填写一个“假”的值就能够了,如如许的Route划定规矩:- routes.MapRoute("Product.List","products/{keywords}/page",new{controller="Product",action="List"});
复制代码 而IIS级其余URLRewrite重写的划定规矩就能够是:- http://kuqin.com/products/helloworld0
复制代码 如许,假如用户输出/products/xxx/2就会被重写成/products/useless-token/2?keywords=xxx——现实上,在第一个示例中我们也能够这么做,只是我“不习气”增添一个假造的值罢了。
以上办理计划能够在IIS6与IIS7的ClassicMode中一般利用,只惋惜在IIS7的IntergratedMode中,多是因为ASP.NET接受了IIS的部分逻辑,因而会很早抛出“IIS级别”,而不是“ASP.NET级别”的BadRequest非常。假如您碰到了这类体例,就要依据KB820129中的体例,经由过程修正服务器真个注册表来同意IIS处置特别字符了(待实验)。
本文来自:http://www.ckuyun.com/JeffreyZhao/archive/2009/09/23/aspnet-mvc-iis-level-url-rewrite.html赵
据说很厉害,甚至可以把C#也干掉^_^,不过也很复杂,本来C++已经够复杂的。有人甚至还提出把这个东东引进标准,我觉得基本上不可能的。 |
|