仅当文件不存在时才会触发HttpHandler

时间:2010-02-15 22:26:26

标签: c# asp.net iis-7 httphandler

我正在尝试创建一个HTTP处理程序来处理对文件夹的所有请求,但我只想要在请求的文件不存在时触发(EG:请求来自文件X,如果X存在我会喜欢服务文件,否则处理程序应该处理它。)

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

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

3 个答案:

答案 0 :(得分:9)

我最终坚持使用处理程序,而是使用以下方法来解决问题:

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

鉴于有这么多人主张模块和捕捉异常,我觉得我应该澄清为什么我不听:

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

答案 1 :(得分: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>

答案 2 :(得分:0)

如果您不想创建HttpModule,我可以想到两个黑客:

  1. 在IIS上使用类似mod-rewrite的重写或IIS上的II7重写,允许存在的特定URL通过,取其他任何内容并将其重定向到静态文件。这可能是一个很大的列表,如果你只有少量的文件,我只建议实现这个hack。
  2. 更改您的网址结构以支持路由脚本,该脚本可以检查文件是否存在并在适当时返回。这种方法可能会影响缓存,所以请谨慎使用。
  3. 雅各