Bezdepbonusu7Программирование: статьи и ответы

Вопрос

ASP.NET MVC - какова самая ранняя точка в цикле запроса, когда вы можете обнаружить запрос статического ресурса?

Автор вопроса: nathanchereОтветов: 3

Чтобы дать этому вопросу некоторый контекст, я написал профилировщик, который вызывается для Application_BeginRequest, но он регистрирует все (например, javascripts, изображения и т. д.). Хотя в крайнем случае можно было бы добавить фильтрацию к клиенту профилировщика, я бы предпочел активировать профилировщик только тогда, когда можно определить, что запрос требует маршрутизации. В идеале это было бы в Application_BeginRequest, но я не думаю, что это было бы возможно без избыточной обработки входящего запроса на маршрутизацию...

Короче говоря, когда наступает самая ранняя точка жизненного цикла запроса, когда я могу определить, относится ли запрос к статическому ресурсу или нет, и как бы вы это сделали?

Возможно ли получить или подключиться к System.Web.Routing.RouteTable и оттуда вызвать мой код профилировщика?

profilingstatic-resource

Ответы

Ответ 1 · рейтинг 2 · Adam Tuliper - MSFT

Существуют различные варианты. Сначала - определить статический файл с помощью Request.PhysicalPath - проверить: Check для статического файла во время Application_BeginRequest?

Одной из альтернатив может быть использование этого в качестве обработчика и использование пути для указания типов файлов, которые необходимо включить (*.aspx), например, в ваш файл web.config. Затем вы можете получить доступ к событиям довольно рано (см. Конвейер asp.net)

Или просто используйте httpmodule - проверьте все и профилируйте только нефизические элементы, как вы упомянули.

Или - используйте свой текущий метод с первой ссылкой, чтобы просто проверить Request.PhysicalPath и надеяться, что это сработает для вас :)

Ответ 2 · рейтинг 2 · Soe Moe

Я бы предпочел использовать фильтры MVC для профилирования, поскольку фильтры MVC позволяют добавлять поведение до и после обработки, а параметр filterContext должен предоставить вам достаточно информации.

Например, я бы создал ProfilerAttribute для профилирования

public class ProfilerAttribute : FilterAttribute, IActionFilter, IResultFilter, IExceptionFilter {
    public void OnActionExecuting(ActionExecutingContext filterContext) {
        Debug.WriteLine("Before Action is executing");
    }

    public void OnActionExecuted(ActionExecutedContext filterContext) {
        Debug.WriteLine("After Action is executed");
    }

    public void OnResultExecuted(ResultExecutedContext filterContext) {
        Debug.WriteLine("After Action Result is executed");
    }

    public void OnResultExecuting(ResultExecutingContext filterContext) {
        Debug.WriteLine("Before Action Result is executing");
    }

    public void OnException(ExceptionContext filterContext) {
        Debug.WriteLine("oops! exception");
    }
}

и зарегистрируйтесь как GlobalFilter в Global.ascx....

public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
    filters.Add(new HandleErrorAttribute());
    filters.Add(new ProfilerAttribute());
}

Надеюсь, это поможет. Спасибо.

обновление: забыл упомянуть, что фильтр MVC выполняется только после сопоставления маршрутизации. Таким образом, вам не нужно отфильтровывать статические ресурсы, поскольку это уже было сделано MVC.

Ответ 3 · рейтинг 1 · nathanchere

Я пробовал подходить к этому с другой стороны, и я намного более доволен результатом. По сути, зачем обнаруживать статические запросы ресурсов, если вы можете вообще не "маршрутизировать" их? В global.asax:

private readonly string[] STATIC_CONTENT_PATHS = new string[] { "css", "js", "img" };

public static void RegisterRoutes(RouteCollection routes)
{
    foreach (string path in STATIC_CONTENT_PATHS) { routes.IgnoreRoute(path + @"/{*foo}"); }

    // other MapRoute calls here
}

Теперь мне больше не нужно проверять статические запросы, хотя, если я по какой-то причине захочу, я все еще могу сделать следующее:

protected void Application_BeginRequest()
{
    if (IsStaticRequest())
    {
         // do something here
    }
}

private bool IsStaticRequest()
{
   var result = Request.Url.AbsolutePath.Split('/');
   if (result.Length < 2) return false;
   return STATIC_CONTENT_PATHS.Contains(result[1]);
}

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы