问题描述
最近公司项目有一个需求是这样的,先说一下,项目用的是纯MongoDB,需求就是用户上传的附件要求在数据库里备份一份,本地静态文件夹中存一份,如果静态文件被人误删,可以通过数据库恢复到本地静态地址。一看到这个需求我就想起了利用防盗链的做法来实现“浏览器输入静态文件地址,后端拦截静态请求,先做判断处理,如果文件被误删,则先恢复后再响应,从而确保静态文件(图片)永远不会丢失“,于是我百度了一下找到了好几种做法,都试了,都不行。先说第一种,自己重写一个IRouteHandler,然后在GetHttpHandler实现中return一个自己重写过的IHttpHandler,在IHttpHandler的实现ProcessRequest中做请求的拦截和需求逻辑处理。写完了在RouteConfig中routes.Add("AttachRoute",newRoute("WebResources/Attach/{mType}/{filename}",newAttachRouteHandler()));结果发现不管用,无论如何都不会命中这个路由,除非把静态地址最后文件名的后缀名从“.”句点符号开始去掉,才可以命中路由。再说第二种,利用ActionFilter+和静态文件夹同名Controller搭配的方法拦截请求做处理,也不行,还是那个问题,无法命中路由。再说第三种,在Global的Application_BeginRequest中做请求的拦截和判断,后来发现,这种方法也是那个问题,如果请求路径中带“.”就进不到这个方法里,应该是被IIS先处理掉了。最后说第4种,也是这种做法最后成功了,但是其中有2个点,我现在都没搞明白到底是什么原理。求解答!我存图片的静态文件夹叫做WebResouce,于是我建了一个WebResouceController,二级目录叫做Attach,于是我写了一个控制器方法Attach,然后配了一条路由,如下:routes.MapRoute("attach","{controller}/{action}/{mType}/{fileName}",new{controller="WebResource",action="Attach"});接着,最关键的来了!要确保RouteConfig中routes.RouteExistingFiles设置为false,且Web.config文件中要加这么一行<system.webServer><modulesrunAllManagedModulesForAllRequests="true"/></system.webServer>然后就能实现输入静态地址,请求进到Controller里了,但是看到一个帖子http://www.cnblogs.com/xishuai/p/Styles-Render-runAllManagedModulesForAllRequests-true-go-on.html这里头说runAllManagedModulesForAllRequests最好不要用,因为它会让所有的静态资源请求都由控制器处理,这样会损耗性能,可是如果不加这一句的话所有的静态资源请求都会被IIS抢先处理掉,怎么办呢?然后RouteConfig中routes.RouteExistingFiles这条设置本来作用是把静态请求转给Controller处理的,可是单单这条设置根本不能实现这个效果,并且如果同时把runAllManagedModulesForAllRequests和RouteExistingFiles设置都设成true会出问题,所有的.html页面都变成404,不知道是什么原因,这2条设置的作用都是把静态请求转给控制器处理,区别在哪里呢?为什么2个设置不能同时使用,又是为什么同时使用了会造成网页404的问题呢?有没有更好切实可行的解决方案也推荐一下,先谢谢各位了
解决方案
解决方案二:
先顶起来,没人知道吗?
解决方案三:
请求1.jpg请求http://IP/controller/action/fileName这个地址,这个方法会在后台用FILE类把文件提出来输出给请求者。如果FILE类找不到文件,调一个方法,从数据库恢复文件,把文件输出给请求者。这有理由有什么关系,看不明白