HttpHandler срабатывает только если файл не существует - PullRequest
7 голосов
/ 16 февраля 2010

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

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

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

Ответы [ 3 ]

9 голосов
/ 16 февраля 2010

Я остановился на обработчике и вместо этого использовал следующее для решения проблемы:

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

Учитывая, что так много людей отстаивают Модули и ловят исключения, я чувствую, что должен уточнить, почему я не слушал:

  1. Это стандартный программный поток, поэтому мне не нравится идея использовать исключение для его запуска, если это не становится абсолютно необходимым.
  2. Это фактически возврат контента при нормальных обстоятельствах. Идея HttpModule на самом деле обрабатывать типичные запросы, а не просто выполнять некоторую базовую совместную обработку и обработку пограничных случаев, кажется немного ошибочной. Поэтому я предпочитаю использовать HttpHandler, поскольку он обрабатывает типичные запросы.
5 голосов
/ 16 февраля 2010

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

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

Вы можете решить, где в жизненном цикле запроса вы хотите выполнить проверку и отреагировать. См. эту статью для некоторого фона

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 голосов
/ 16 февраля 2010

Если вы предпочитаете не создавать HttpModule, я могу подумать о двух взломах:

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

Jacob

...