目录
因项目需要,对于部分控制器需要实现伪静态方便搜索引擎优化(SEO),过程比较曲折,简单的记录一下。
1.什么是伪静态?为什么要实现伪静态?
伪静态:动态网页通过重写URL的方法实现去掉动态网页的参数,但在实际的网页目录中并没有必要实现存在重写的页面。
例如:我们当访问地址http://www.cnblogs.com/ForEvErNoME/archive/2012/06/05/2529259.html时,你会认为在站点服务器下存在名为2529259.html文件,其实实际上它可能是不存在的,而可能你看到的内容是通过重定向/archive/article.aspx?year=2012&month=06&day=05&id=2529259显示出来的。
为什么要这样做呢?
(1)增强URL的友好性,方便用户记忆URL。
(2)提高搜索引擎抓取,很多搜索引擎更看好静态HTML页。
(3)加强安全性,因为隐藏了参数"year"、"month"、"day"、"id",使网站没有那么容易受到攻击。
以上内容摘选自:ASP.NET伪静态实现
2.实现APS.NET MVC伪静态的方式有哪些?
- 通过实现接口IHttpHandler来接管HTTP请求,这里需要使用URLRewriter这个扩展,大家可以在NuGet管理工具中下载。想通过这种方式大家可以参考这篇几篇文章:ASP.NET伪静态实现ASP.NET MVC4通过UrlRewriter配置伪静态
- 通过配置默认路由的方式来实现伪静态。这种是比较常用的方法之一,大家可以参考这篇文章:asp.net mvc5 伪静态 WebForm
- 通过使用ASP.NET MVC5特性路由的方式,这就是本文使用的方式,为什么笔者使用这种方式呢?是因为我们项目是一个老项目添加新功能,如果贸然全站伪静态那么很多写好的代码需要返工,如果项目中只有少数几个控制器需要伪静态那么我也建议使用这种方式。
3.那么如何实现使用ASP.NET MVC5的伪静态呢?
同样,分为几个步骤。
(1)在路由注册中启用特性路由
如果大家不懂什么是特性路由,可以参考这篇文章
就是在/App_Start/RouteConfig.cs中添加一行代码.
routes.MapMvcAttributeRoutes();
(2)为需要伪静态的方法添加特性路由
笔者是News Action需要实现伪静态。
[Route("~/News")]
[Route("~/News/{page:int}.html")]
(3) 在Web.Config中,为*.html路径配置处理程序。
在这里笔者需要给大家科普一下,网上有很多帖子都是直接在Web.Config配置节中添加这样一句配置代码。在前面asp.net mvc5 伪静态 WebForm中作者也是这么做的,但是我们是不推荐使用这种方式。因为它有较大的性能损失。
我会在本文解释一下原因,想深入探究的朋友可以参考:Link
<modules runAllManagedModulesForAllRequests="true" />
大家可以看下图,这是IIS 7.0的处理机制,大家可以看到ExecuteHandler这个部分,默认情况下的话是通过这样一个机制来处理,如果我们使用这个配置项,那么不管是CGI、静态文件都是通过ISAPI也就是我们的ASP.NET程序来执行,一些Js文件、css文件或者图片都会走我们的ASP.NET程序,那么将会造成很多性能损失,这是我所在乎的一个原因,当然还有关于IIS身份验证等问题。有兴趣的朋友可以参考这篇文章:Link
所以基于上面这样一些原因,我们使用单独配置只对*.html进行配置,那么其它静态文件都是走IIS 7.0默认处理程序,只有需要达到伪静态的.html才进入ASP.NET进行处理。以下是配置节。
<system.webServer>
<handlers>
<add name="Static64" path="*.html" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="Static32" path="*.html" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="(Static) ExtensionlessUrlHandler-Integrated-4.0" path="*.html" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
大家可以发现我分别添加了Static64、Static32、(Static) ExtensionlessUrlHandler-Integrated-4.0三个配置,其中主要的功能就是将*.html为后戳的请求交给aspnet_isapi进行处理。关于该配置节的具体信息,大家可以参考MSDN
(4) 验证
已经可以正常访问,通过我们的伪静态请求,完成了项目需求。
笔者水平有限,如果错误欢迎大家批评指正!
参考文档
https://www.cnblogs.com/ForEvErNoME/archive/2012/06/14/2549313.html
https://www.cnblogs.com/ForEvErNoME/archive/2012/06/14/2549313.html
http://blog.csdn.net/just_shunjian/article/details/51132866
https://www.cnblogs.com/zengpeng/p/5899885.html
https://www.cnblogs.com/zengpeng/p/5899885.html
https://www.cnblogs.com/xishuai/archive/2015/01/06/Styles-Render-runAllManagedModulesForAllRequests-true.html
http://blog.csdn.net/shandian84/article/details/40903663
https://msdn.microsoft.com/zh-cn/library/bb763179%28v=vs.100%29.aspx