ASP.NET MVC - какова самая ранняя точка в цикле запроса, когда вы можете обнаружить запрос статического ресурса?
Автор вопроса: nathanchereОтветов: 3
Чтобы дать этому вопросу некоторый контекст, я написал профилировщик, который вызывается для Application_BeginRequest, но он регистрирует все (например, javascripts, изображения и т. д.). Хотя в крайнем случае можно было бы добавить фильтрацию к клиенту профилировщика, я бы предпочел активировать профилировщик только тогда, когда можно определить, что запрос требует маршрутизации. В идеале это было бы в Application_BeginRequest, но я не думаю, что это было бы возможно без избыточной обработки входящего запроса на маршрутизацию...
Короче говоря, когда наступает самая ранняя точка жизненного цикла запроса, когда я могу определить, относится ли запрос к статическому ресурсу или нет, и как бы вы это сделали?
Возможно ли получить или подключиться к System.Web.Routing.RouteTable и оттуда вызвать мой код профилировщика?
Одной из альтернатив может быть использование этого в качестве обработчика и использование пути для указания типов файлов, которые необходимо включить (*.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....
обновление: забыл упомянуть, что фильтр 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]);
}
Поскольку я абсолютно точно знаю, какие единственные пути, по которым я буду обслуживать статический контент, это кажется довольно надежным решением. Я все еще открыт для других идей, но я думаю, что это соответствует моим потребностям.