2010-02-15 12 views
7

Estoy tratando de crear un controlador HTTP para manejar todas las solicitudes a una carpeta, pero solo quiero que se active si los archivos solicitados no existen (por ejemplo, la solicitud entra en vigor archivo X, si X existe me gustaría servir el archivo, de lo contrario el manejador debería tratar con él).HttpHandler se activa solo si el archivo no existe

Los archivos solo serán contenido estático, no scripts en sí mismos, lo que supongo que lo hace un poco más fácil, pero parece que no puedo encontrar nada que lo solucione ... ¿Alguien tiene alguna idea? Lo que supongo que se puede hacer desde el módulo de reescritura IIS7 puede manejarlo, pero no puedo ver cómo ...

Editar Solo para aclarar ... el manejador es el caso típico y no es un error - Manejando la rutina pero en realidad entregando el contenido apropiado. Solo quiero la posibilidad de agregar nuevos archivos a la carpeta, ya sea como cosas separadas o como sobrecargas de lo que entregaría el controlador.

+0

código de trabajo muestra en la respuesta. –

Respuesta

9

he terminado la pervivencia de un controlador y en su lugar mediante el siguiente para resolver el problema:

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

dado tantas personas abogaron Módulos y excepciones que cogen siento que debería aclarar por qué no le hice caso:

  1. Este es el flujo del programa estándar, como tal, no me gusta la idea de usar una excepción a desencadenarla a menos que sea absolutamente necesario.
  2. Esto realmente devuelve contenido en circunstancias normales. La idea de que HttpModule realmente maneje solicitudes típicas en lugar de simplemente hacer un procesamiento compartido básico y manejar casos extremos parece un poco desalentador. Como tal, prefiero usar un HttpHandler ya que está manejando las solicitudes típicas.
+1

Muy bien: mi respuesta de la corriente de la noche tardía se basó en tener A). ya hecho esto aprovechando un controlador de excepción global existente, y B).optimizando para el caso donde el archivo * does * existe. Creo que tienes el enfoque correcto donde quieres optimizar para el caso 404. – annakata

+0

Para el resto de nosotros, @annakata, ¿a dónde fue tu respuesta? :( – BrainSlugs83

+0

La solución de annakata era, según recuerdo, muy similar a la solución de Sky Sanders a continuación. Esto es utilizar un HttpModule para encargarse del procesamiento cuando el archivo no existe en lugar de utilizar un HttpHandler que maneja ambos casos. la aplicación particular realmente se reduce a lo que refleja la verdadera intención de diseño con mayor precisión (El caso en el que recomendaría un controlador proviene de los dos puntos en mi respuesta). – fyjham

5

Probablemente le gustaría implementar un HttpModule. De lo contrario, estás peleando con todos los otros HttpHandlers que están compitiendo por la solicitud.

Esto debería empezar ....

Usted puede decidir en qué parte del ciclo de vida del pedido que desea realizar su cheque y reaccionar. Ver this article para algunos antecedentes

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

Si usted prefiere no crear una HttpModule, puedo pensar en dos cortes:

  1. usar algo como mod-rewrite en Apache o II7 reescriben en IIS para permitir el paso de URLs específicas, tomar cualquier otra cosa y redirigirlo a su archivo estático. Esta podría ser una lista grande y solo recomendaría implementar este truco si solo tienes una pequeña cantidad de archivos.
  2. Cambie la estructura de su URL para que admita un script de enrutamiento que pueda verificar si el archivo existe y devolverlo cuando corresponda. Este enfoque probablemente afectará el almacenamiento en caché, por lo tanto, tenga cuidado.

Jacob

Cuestiones relacionadas