2010-02-15 41 views
7

我正在尝试创建一个HTTP处理程序来处理对文件夹的所有请求,但我只希望在请求的文件不存在的情况下触发它(EG:Request for for文件X,如果X存在我想提供该文件,否则处理程序应该处理它)。HttpHandler只有在文件不存在的情况下才会触发

这些文件将只是静态内容,而不是脚本本身,我认为它使得它更容易一点,但我似乎无法找到任何可以做到这一点的任何东西......任何人有任何想法?我认为它可以完成,因为IIS7重写模块可以管理它,但我不知道如何...

编辑只是为了澄清...处理程序是典型的情况下,它不是一个错误处理例程,但实际提供适当的内容。我只是希望能够将新文件添加到文件夹,作为单独的东西或作为处理程序将传递的重载。

+0

工作代码示例在答案中。 – 2010-02-16 01:18:26

回答

9

我已经结束了与处理器贴合,而不是使用下面要解决的问题:

if (File.Exists(context.Request.PhysicalPath)) context.Response.TransmitFile(context.Request.PhysicalPath); 
else { /* Standard handling */ } 

鉴于如此多的人主张模块和捕获异常,我觉得我应该澄清为什么我没听:

  1. 这是标准的程序流程,因为我不喜欢使用例外触发它的想法除非它变得绝对必要。
  2. 这实际上是在正常情况下返回内容。 HttpModule实际上处理典型请求的想法,而不仅仅是做一些基本的共享处理和处理边缘案例似乎有点偏离。因此,我更喜欢使用HttpHandler,因为它正在处理典型的请求。
+1

够公平 - 我深夜的意识流答案是基于A)。已经利用现有的全局异常处理程序完成了这一工作,并且B)。针对文件*存在的情况进行优化。我认为你有正确的方法,你想为404案例进行优化。 – annakata 2010-02-16 19:55:17

+0

对于我们其他人,@annakata,你的答案去了哪里? :( – BrainSlugs83 2012-10-13 06:38:36

+0

)我记得,annakata的解决方案非常类似于下面的Sky Sanders的解决方案,当文件不存在时,使用HttpModule接管处理,而不是使用处理两种情况的HttpHandler。特定的应用程序真的可以归结为更准确地反映真正的设计意图(我建议处理程序的情况来自我答案中的两个点)。 – fyjham 2012-11-19 03:49:27

5

也许你会想实现一个HttpModule。否则,你正在与争夺请求的所有其他HttpHandler进行斗争。

这应该让你开始....

您可以决定在请求生命周期要执行的检查和反应。见this article一些背景

using System; 
using System.IO; 
using System.Web; 

namespace RequestFilterModuleTest 
{ 
    public class RequestFilterModule : IHttpModule 
    { 
     #region Implementation of IHttpModule 

     /// <summary> 
     /// Initializes a module and prepares it to handle requests. 
     /// </summary> 
     /// <param name="context"> 
     /// An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, 
     /// properties, and events common to all application objects within an ASP.NET application 
     /// </param> 
     public void Init(HttpApplication context) 
     { 
      context.BeginRequest += ContextBeginRequest; 
     } 

     /// <summary> 
     /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>. 
     /// </summary> 
     public void Dispose() 
     { 
     } 

     private static void ContextBeginRequest(object sender, EventArgs e) 
     { 
      var context = (HttpApplication) sender; 

      // this is the file in question 
      string requestPhysicalPath = context.Request.PhysicalPath; 

      if (File.Exists(requestPhysicalPath)) 
      { 
       return; 
      } 

      // file does not exist. do something interesting here..... 
     } 

     #endregion 
    } 
} 

<?xml version="1.0"?> 
<configuration> 
    ............................... 
    <system.web> 
    ........................... 
     <httpModules> 
      <add name="RequestFilterModule" type="RequestFilterModuleTest.RequestFilterModule"/> 
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     </httpModules> 
    </system.web> 
    ................... 
</configuration> 
0

如果你宁愿不创建一个HttpModule,我能想到2名黑客:

  1. 使用像国防部重写上Apache或II7会在IIS上重写,以允许存在的特定URL经历其他任何操作并将其重定向到静态文件。这可能是一个很大的列表,如果你只有少量的文件,我只会推荐实施这个黑客。
  2. 更改您的URL结构以支持路由脚本,该脚本可以检查文件是否存在并在适当时返回。这种方法可能会影响缓存,所以请谨慎使用。

雅各

相关问题