0

In my site, because I have a lot of resources, asynchronously loaded panels, compressed scripts and styles etc everytime I debug the BeginRequest method in Global.asax it tends to get hit 5 or 6 times due to all the content requests.

    public MvcApplication()
    {
        BeginRequest += MvcApplication_BeginRequest;
        EndRequest += MvcApplication_EndRequest;
        AcquireRequestState += MvcApplication_AcquireRequestState;
    }

    private void MvcApplication_BeginRequest(object sender, EventArgs e)
    {
        var nHibernateContext = Ioc.ContainerWrapper.Resolve<INHibernateContext>();
        CurrentSessionContext.Bind(nHibernateContext.SessionFactory.OpenSession());

        MyMethodWithSomeComplexCookieLogic();
    }

I would ideally want my MyMethodWithSomeComplexCookieLogic() to be processed only once with every page load and not 5 or 6 times depending on the page I am going.

Is there a way to filter the main page BeginRequest from all the smaller requests?

Alternatively where else can this logic be moved to make sure that it is handled once on every page load globally?

I have done some reading and I can't find an appropriate solution.

I tried creating a Filter Attribute:

public class MyMethodFilterAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        base.OnResultExecuting(context);

        /* my logic */
    }
}

And I registered that in Global.asax

    private static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new MyMethodFilterAttribute());
    }

But it gets hit 5 or 6 times.

Is MVC unable to support a similar functionality to the Page_Load? In a classic .NET application the events get only hit once.

Thank you

Nick
  • 2,877
  • 2
  • 33
  • 62
  • Have you tried decorating only the appropriate controller actions with the `MyMethodFilterAttribute` attribute, instead of adding it to the global filter collection? For example, if you decorate the `Home` controller's `Index` action, the filter's code will get hit only once when loading the homepage. – elolos Oct 13 '14 at 14:56
  • I want this to apply everywhere because the project has hundreds of controllers and it needs to apply on all the "GET" actions. Also I want to spare us from the pain of including it manually everytime we add a new controller or action. – Nick Oct 13 '14 at 15:27
  • What you're saying makes sense. What percentage of the `GET` actions do you want excluded from the filter? If it's relatively low, you could approach this from the opposite direction and create an "exclude" attribute to decorate these actions. – elolos Oct 13 '14 at 15:46

1 Answers1

0

In MVC, action filters are the correct place for this sort of thing.

Your requests for static files shouldn't be hitting action filters as they won't be routed through controller actions. This leaves you with the issue of your AJAX requests. The simple solution to this is to do the following:

public class MyMethodFilterAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        if(!context.HttpContext.Request.IsAjaxRequest())
        {
            // Your logic
        }

        base.OnResultExecuting(context);
    }
}

You should now be able to place a breakpoint somewhere among your logic and only have it hit for non-AJAX requests.

Ant P
  • 24,820
  • 5
  • 68
  • 105
  • Promising but I believe not all my requests are Ajax requests. Some are for javascript files, or stylesheets and images. I'll check this and will confirm shortly – Nick Oct 13 '14 at 15:06