2010-02-15 4 views
7

Я пытаюсь создать обработчик HTTP для обработки всех запросов в папку, но я только хочу, чтобы он срабатывал, если запрошенные файлы не существуют (EG: запрос приходит файл X, если существует X, я хотел бы обслуживать файл, иначе обработчик должен иметь дело с ним).HttpHandler пожар только в том случае, если файл не существует

Файлы будут только статическим содержимым, а не самими сценариями, которые, как я полагаю, делают его немного легче, но я не могу найти ничего, что сделает трюк ... У кого-нибудь есть идеи? Я предполагаю, что это можно сделать, так как модуль перезаписи IIS7 может управлять им, но я не вижу, как ...

Редактировать Просто, чтобы уточнить ... обработчик является типичным случаем, и это не ошибка рутинная обработка, но фактически предоставление соответствующего контента. Я просто хочу, чтобы добавить новые файлы в папку либо в виде отдельных вещей, либо в виде перегрузок, которые будет выполнять обработчик.

+0

рабочий код образец в ответе. –

ответ

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

+0

Для всех нас, @annakata, где был ваш ответ? :( – BrainSlugs83

+0

Решение annakata было, как я помню, очень похоже на решение Sky Sanders ниже. Это использование HttpModule для обработки, когда файл не существует, а не с использованием HttpHandler, который обрабатывает оба случая. конкретное приложение действительно сводится к тому, что более точно отражает истинное намерение дизайна (случай, когда я рекомендую обработчик, состоит из двух точек в моем ответе). – fyjham

5

Возможно, вы захотите реализовать HttpModule. В противном случае вы сражаетесь со всеми другими HttpHandlers, которые соперничают за запрос.

Это поможет вам начать ....

Вы можете решить, где в жизненном цикле запроса вы хотите, чтобы выполнить вашу проверку и реагировать. См 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, я могу думать о двух писак:

  1. использовать что-то вроде мод-переписать на Apache или II7 переписываются в IIS, чтобы разрешить определенные URL-адреса, которые существуют для прохождения, взять что-нибудь еще и перенаправить его в ваш статический файл. Это может быть большой список, и я бы рекомендовал реализовать этот хак, если у вас есть только небольшое количество файлов.
  2. Измените свою структуру URL-адресов, чтобы поддерживать скрипт маршрутизации, который может проверить, существует ли файл и как его вернуть. Этот подход, скорее всего, повлияет на кеширование, поэтому, пожалуйста, будьте осторожны.

Jacob

Смежные вопросы